I want to use getopt in a bash script to handle the options for the script. I want one of my options to be any additional arguments which are to be passed to one of the command in the script.

To be specific, I am making a folder backup script which calls rdiff-backup. The options look like below:

 TEMP=`getopt -o s:l:r:n:e:m:k:d:a: --long source-dir:,local-dest-dir:,remote-dest-dir:,logger-name:,err-report-dir:,email-receiver:,remove-older-than:,remote-dest-server:,additional-rdi>
              -n 'rdiff_backup_dir' -- "$@"`
      if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
 # Note the quotes around `$TEMP': they are essential!
 eval set -- "$TEMP"
      while true; do
   case "$1" in
     -s | --source-dir ) folder_to_backup="$2"; shift 2 ;;
     -l | --local-dest-dir ) local_backup_folder="$2"; shift 2 ;;
     -r | --remote-dest-dir ) remote_server_backup_folder="$2"; shift 2 ;;
     -d | --remote-dest-server ) backup_server="$2"; shift 2 ;;
     -n | --logger-name ) logger_name="$2"; shift 2 ;;
     -e | --err-report-dir ) error_report_dir="$2"; shift 2 ;;
     -m | --email-receiver ) email_receiver="$2"; shift 2 ;;
     -k | --remove-older-than ) remove_older_than="$2"; shift 2 ;;
     -a | --additional-rdiff-backup-args ) additional_rdiff_backup_args="$2"; shift 2 ;;
     -- ) shift; break ;;
     * ) break ;;

I want to later call rdiff-backup in the script like this, giving it as arguments and of the extra arguments specified by the user.

rdiff-backup  \
       --ssh-no-compression \
       ${additional_rdiff_backup_args} \
       "${folder_to_backup}" "${local_backup_full_path}/" 2> "${error_report_dir}/${folder_to_backup_basename}_$(hostname).txt"

However, before even testing this setup, I have fallen at the first hurdle of trying to put the additional arguments into a variable, and pass them to the script like the following:

additional-rdiff-backup-args="--exclude "${nc_data_dir}/data/.opcache" --exclude "${nc_data_dir}/data/access.log" --exclude "${nc_data_dir}/data/error.log"  --exclude "${nc_data_dir}/dat>

rdiff-backup-dir --source-dir ${nc_data_dir} \
                 --local-dest-dir ${local_backup_location} \
                 --remote-dest-server ${backup_server} \
                 --remote-dest-dir ${remote_server_backup_folder} \
                 --remove-older-than 6M
                 --additional-rdiff-backup-args "${additional-rdiff-backup-args}"

The line creating the arguments to pass to the script fails with the error No such file or directory. A simple attempt to build a similar arg string also fails

# additional-rdiff-backup-args="--exclude "${HOME}""
bash: additional-rdiff-backup-args=--exclude /root: No such file or directory

So my question is, why is the above failing, and what is the correct way to pass these arguments into the script for use by a command within the script?


1 Answer 1


I would suggest you rethink your script's interface. The safe way to do this is to separate your script's options from the commands's options with --

rdiff-backup-dir --source-dir "${nc_data_dir}" \
                 --local-dest-dir "${local_backup_location}" \
                 --remote-dest-server "${backup_server}" \
                 --remote-dest-dir "${remote_server_backup_folder}" \
                 --remove-older-than 6M \
                 -- \
                 --exclude "${nc_data_dir}/data/.opcache" \
                 --exclude "${nc_data_dir}/data/access.log" \
                 --exclude "${nc_data_dir}/data/error.log"  \
                 --exclude "${nc_data_dir}/dat...

Then, after the getopt while loop, everything after -- is still in the positional parameters, aka "$@", and thus still available as individual words.

  • Thanks, I will try it!
    – crobar
    Dec 10, 2021 at 4:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.