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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .