0

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 ;;
   esac
 done

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

1 Answer 1

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.

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

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.