Bash: Backup on cd
From FVue
Contents
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
Advertisement