diff --git a/CHANGELOG b/CHANGELOG index 545e965..847a328 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +0.8 (05 August 2012) +=================== + * Improved argument parsing. Now the script is insensitive to the order of appearance of the options and handles correctly optional options parameters + * Re-added possibility to specify the config file on the command line, which is now th recommanded way to do (facilitating script updates) + * Fix "unary operator expected warning" in some rare cases + 0.7.1 (9 July 2012) =================== * Adding 'duplicity-backup.conf' to .gitignore diff --git a/README b/README index 5199f14..25eb7ea 100644 --- a/README +++ b/README @@ -57,9 +57,16 @@ CONFIGURATION The configuration takes place in a separate config file and is documented there. -The script looks for its configuration by reading the config file specified in -the CONFIG parameter at the beggining of the script. Be sure to edit it to match -the actual location of your config file. +The script looks for its configuration by reading the config file specified by +the command line option -c and fallback on the CONFIG parameter at the beggining +of the script otherwise. + +Be sure to specify it on the command line or to edit the CONFIG parameter in the +script to match the actual location of your config file. + +NOTE: to ease future updates of the script, you may want not to edit the script + at all and to specify systematically the path to your config file on the + command line with the -c option. COMMON USAGE EXAMPLES ===================== @@ -68,36 +75,36 @@ COMMON USAGE EXAMPLES $ duplicity-backup.sh * Run an incremental backup: - $ duplicity-backup.sh --backup + $ duplicity-backup.sh [-c config_file] --backup * Force a one-off full backup: - $ duplicity-backup.sh --full + $ duplicity-backup.sh [-c config_file] --full * Restore your entire backup: - $ duplicity-backup.sh --restore + $ duplicity-backup.sh [-c config_file] --restore You will be prompted for a restore directory - $ duplicity-backup.sh --restore /home/user/restore-folder + $ duplicity-backup.sh [-c config_file] --restore /home/user/restore-folder You can also provide a restore folder on the command line. * Restore a specific file in the backup: - $ duplicity-backup.sh --restore-file + $ duplicity-backup.sh [-c config_file] --restore-file You will be prompted for a file to restore to the current directory - $ duplicity-backup.sh --restore-file img/mom.jpg + $ duplicity-backup.sh [-c config_file] --restore-file img/mom.jpg Restores the file img/mom.jpg to the current directory - $ duplicity-backup.sh --restore-file img/mom.jpg /home/user/i-love-mom.jpg + $ duplicity-backup.sh [-c config_file] --restore-file img/mom.jpg /home/user/i-love-mom.jpg Restores the file img/mom.jpg to /home/user/i-love-mom.jpg * List files in the remote archive - $ duplicity-backup.sh --list-current-files + $ duplicity-backup.sh [-c config_file] --list-current-files * Verify the backup - $ duplicity-backup.sh --verify + $ duplicity-backup.sh [-c config_file] --verify * Backup the script and gpg key (for safekeeping) - $ duplicity-backup.sh --backup-script + $ duplicity-backup.sh [-c config_file] --backup-script TROUBLESHOOTING =============== diff --git a/duplicity-backup.sh b/duplicity-backup.sh index c8c957e..ec45ab1 100755 --- a/duplicity-backup.sh +++ b/duplicity-backup.sh @@ -27,14 +27,75 @@ # # ---------------------------------------------------------------------------- # -# Set config file (don't forget to copy duplicity-backup.conf.example to -# match that path) +# Default config file (don't forget to copy duplicity-backup.conf.example to +# match that path) +# NOTE: It can be useful not to edit this script at all to ease future updates +# so the config file can be specified directly on the command line too +# with the -c option. CONFIG="duplicity-backup.conf" ############################################################## # Script Happens Below This Line - Shouldn't Require Editing # ############################################################## +# Some expensive argument parsing that allows the script to +# be insensitive to the order of appearance of the options +# and to handle correctly option parameters that are optional +while getopts ":c:-:" opt; do + case $opt in + # parse long options (a bit tricky because builtin getopts does not + # manage long options and i don't want to impose GNU getopt dependancy) + -) + case "$OPTARG" in + backup | full | verify | list-current-files | collection-status | help) + COMMAND=$OPTARG + ;; + # --restore [restore dest] + restore) + COMMAND=$OPTARG + # We try to find the optional value [restore dest] + if [ ! -z "${!OPTIND:0:1}" -a ! "${!OPTIND:0:1}" = "-" ]; then + RESTORE_DEST=${!OPTIND} + OPTIND=$(( $OPTIND + 1 )) # we found it, move forward in arg parsing + fi + ;; + # --restore-file [file to restore] [restore dest] + restore-file) + COMMAND=$OPTARG + # We try to find the first optional value [file to restore] + if [ ! -z "${!OPTIND:0:1}" -a ! "${!OPTIND:0:1}" = "-" ]; then + FILE_TO_RESTORE=${!OPTIND} + OPTIND=$(( $OPTIND + 1 )) # we found it, move forward in arg parsing + else + continue # no value for the restore-file option, skip the rest + fi + # We try to find the second optional value [restore dest] + if [ ! -z "${!OPTIND:0:1}" -a ! "${!OPTIND:0:1}" = "-" ]; then + RESTORE_DEST=${!OPTIND} + OPTIND=$(( $OPTIND + 1 )) # we found it, move forward in arg parsing + fi + ;; + *) + echo "Invalid option: --$OPTARG" >&2 + COMMAND=$OPTARG + ;; + esac + ;; + # here are parsed the short options + c) # set the config file from the command line + CONFIG=$OPTARG + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + COMMAND="" + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + COMMAND="" + ;; + esac +done + # Read config file if specified if [ ! -z "$CONFIG" -a -f "$CONFIG" ]; then @@ -322,13 +383,13 @@ echo -e "-------- START DUPLICITY-BACKUP SCRIPT --------\n" >> ${LOGFILE} get_lock -case "$1" in - "--backup-script") +case "$COMMAND" in + "backup-script") backup_this_script exit ;; - "--full") + "full") OPTION="full" include_exclude duplicity_backup @@ -336,7 +397,7 @@ case "$1" in get_file_sizes ;; - "--verify") + "verify") OLDROOT=${ROOT} ROOT=${DEST} DEST=${OLDROOT} @@ -355,11 +416,11 @@ case "$1" in echo -e "Verify complete. Check the log file for results:\n>> ${LOGFILE}" ;; - "--restore") + "restore") ROOT=$DEST OPTION="restore" - if [[ ! "$2" ]]; then + if [[ ! "$RESTORE_DEST" ]]; then echo "Please provide a destination path (eg, /home/user/dir):" read -e NEWDESTINATION DEST=$NEWDESTINATION @@ -372,30 +433,28 @@ case "$1" in exit 1 fi else - DEST=$2 + DEST=$RESTORE_DEST fi echo "Attempting to restore now ..." duplicity_backup ;; - "--restore-file") + "restore-file") ROOT=$DEST INCLUDE= EXCLUDE= EXLUDEROOT= OPTION= - if [[ ! "$2" ]]; then + if [[ ! "$FILE_TO_RESTORE" ]]; then echo "Which file do you want to restore (eg, mail/letter.txt):" read -e FILE_TO_RESTORE echo - else - FILE_TO_RESTORE=$2 fi - if [[ "$3" ]]; then - DEST=$3 + if [[ "$RESTORE_DEST" ]]; then + DEST=$RESTORE_DEST else DEST=$(basename $FILE_TO_RESTORE) fi @@ -420,7 +479,7 @@ case "$1" in duplicity_backup ;; - "--list-current-files") + "list-current-files") OPTION="list-current-files" ${DUPLICITY} ${OPTION} ${VERBOSITY} ${STATIC_OPTIONS} \ $ENCRYPT \ @@ -428,7 +487,7 @@ case "$1" in echo -e "-------- END --------\n" >> ${LOGFILE} ;; - "--collection-status") + "collection-status") OPTION="collection-status" ${DUPLICITY} ${OPTION} ${VERBOSITY} ${STATIC_OPTIONS} \ $ENCRYPT \ @@ -436,7 +495,7 @@ case "$1" in echo -e "-------- END --------\n" >> ${LOGFILE} ;; - "--backup") + "backup") include_exclude duplicity_backup duplicity_cleanup @@ -449,6 +508,8 @@ case "$1" in `basename $0` [options] Options: + -c config_file : specify the config file to use + --backup: runs an incremental backup --full: forces a full backup