Bash: Backup on cd

From FVue
Jump to: navigation, search

Problem

I want to backup my projects on a CDRW, via bash. The script has to detect if the backup can be added to a multi-session cd or if the cd needs to be blanked.

Solution

#!/bin/bash
#--- backup.sh ----------------------------------------------------------
# Create backup on cd
# Usage: backup.sh [options]
# Available options are:
# --burn  Burn only.  No dar file generation.



set -u
trap 'wrapexit $?' 1 2 3 15 ERR


function wrapexit() {
    local exit_status=$?
    echo "$(date) $0 Exitting with status $exit_status";
    exit $exit_status
} # wrapexit


# Get info from current loaded cd
# @param string $1  Name of device containing the cd.
# @return
# @global string $cdIsMultiSession  1 if cd is multi-session, 0 if not
# @global string $cdMultiSessionInfo  Format: last_sess_start,next_sess_start
#    The first number is the sector number of the first sector in the last 
#    session of the disk that should be appended to.  The second number is 
#    the starting sector number of the new session.
#    Example values are:
#    0,-1       : readonly CD
#    0,24448    : multi-session CD with one previous session
#    null       : blank CD:
# @global integer $cdLastSessionStart  Starting sector number of last successful written session.
# @global integer $cdNextSessionStart  Starting sector number of new session.
# @global integer $cdNextSessionNr     Session number of new session, origin = 0.
function getCdInfo() {
        # Retrieve maximum number of blocks on cd
    cdMaxNrOfBlocks=`\
        sudo cdrecord dev=$1 -atip 2> /dev/null |\
        sed -rn 's/^  ATIP start of lead out: ([0-9]+).*/\1/ p'`
    cdIsMultiSession=1
    cdLastSessionStart=
    cdMkisofsMultiSessionOptions=
    cdMultiSessionInfo=`sudo cdrecord -msinfo dev=$1`
    cdNextSessionNr=0
    cdNextSessionStart=
    if [ $cdMultiSessionInfo ]; then
        cdLastSessionStart="`echo $cdMultiSessionInfo | awk -F, '{ print $1 }'`"
        cdNextSessionStart="`echo $cdMultiSessionInfo | awk -F, '{ print $2 }'`"
        cdMkisofsMultiSessionOptions="-C $cdMultiSessionInfo -M $1"
        cdNextSessionNr=2  # Or greater...
        if (( $cdNextSessionStart == -1 )); then
            cdIsMultiSession=0
        elif (( $cdLastSessionStart == 0 )); then
            cdNextSessionNr=1
        fi
    fi
} # getCdInfo()


# Determine lead size
# See http://gd.tuwien.ac.at/utils/schilling/cdrecord/README.multi
# Uses:
# @global integer $cdNextSessionNr  Session number, origin = 0.
function leadSize() {
    (( $cdNextSessionNr < 2 )) && echo 11400 || echo 6900
} # leadSize()



backupDir=/tmp/proj/backup
if [[ $# > 0 && $1 == --burn ]]; then
    backupNameDar=$backupDir/$(basename $(find $backupDir -name backup$(date +%Y%m%d)\*) .1.dar)
else
    backupNameDar=$backupDir/backup$(date +%Y%m%d_%H%M)
fi
backupFile=$backupNameDar.1.dar
backupIso=$backupDir/backup.iso
backupDev=/dev/hdc


echo "$(date) backupNameDar=$backupNameDar"

if [[ $# == 0 ]]; then  # Not --burn only
        # Make sure backup dir exists
    test -d $backupDir || mkdir -p $backupDir
        # Remove previous backup, if any
    test -f $backupFile && rm --force $backupFile
        # Remove previous iso, if any
    test -f $backupIso && rm --force $backupIso

        # Log last date
        # This date is used by the automatic test
    date '+%Y%m%d' > log/lastdate
        # Make new backup.  Options:
        # -s: Max size of slice
        # -B: configuration file
        # -Q: suppress the initial warning when not run from a tty
    dar -c $backupNameDar -B darrc -Q -s 650M > /dev/null
fi

    # Get cd info
getCdInfo $backupDev
    # Calculate size of ISO file
backupIsoSize=$(
    sudo mkisofs $cdMkisofsMultiSessionOptions -input-charset utf-8 -print-size -R \
    -quiet $backupFile
)


    # Bias to blank cd
doBlankCd=1
    # Is cd multi-session?
if (( $cdIsMultiSession )); then
    # Yes, cd is multi-session;
        # Does backup fit on cd?
    if (( $cdNextSessionStart + $backupIsoSize + `leadSize` < $cdMaxNrOfBlocks )); then
        # Yes, backup fits on cd;
            # Indicate to not blank cd
        doBlankCd=0
    fi
fi

    # Must cd be blanked?
if (( $doBlankCd )); then
    # Yes, cd must be blanked;
        # Blanking cd is successful?
    if sudo cdrecord blank=fast dev=$backupDev speed=2; then
        # Yes, blanking cd is successful;
            # Indicate new session
        cdNextSessionNr=0
            # Reset multi-session options
        cdMkisofsMultiSessionOptions=
    else
        # No, blanking cd isn't successful;
            # Exit with errorcode
        echo "$0: error blanking cd" >&2
        exit $?
    fi
fi

    # Create ISO file.  Options:
    # -R: Use the Rock Ridge protocol to further describe the files on the iso9660 filesystem.
sudo mkisofs $cdMkisofsMultiSessionOptions -input-charset utf-8 -o $backupIso -R $backupFile
    # Write ISO file to CD-R(W)
    # NOTE: Add line underneath to '/etc/sudoers' to allow executing 'cdrecord' and 'mkisofs' as root:
    #
    #    myname ALL = NOPASSWD: /usr/bin/cdrecord,/usr/bin/mkisofs
    #
sudo cdrecord -multi -v -tao speed=2 dev=$backupDev $backupIso

See also

BashBurn
Cd burning shell script. Very complete CD-burning application written in bash.
Bash: Catch error
Detailed howto catch errors in bash
CD Writing Howto - Multisession CD-ROMs
Detailed information on how to write multisession CD-ROMs using the command-line

Comments

blog comments powered by Disqus