0

All the other solutions on SO work well for echo and similar commands. However, I am trying to assign a long list of arguments (split across multiple lines) to a single variable, which will be expanded into multiple arguments for an rsync command. Something about the rsync command (or bash's whitespace tokenizing) doesn't work well with most of the recommended solutions.

SYNC_OPTIONS="-a --progress --delete --delete-before --delete-excluded"
SYNC_EXCLUDE="
    --exclude='some/dir/with spaces/requiring quoting'
    --exclude='another/dir/with spaces'
    --exclude='blah blah/blah'
    "
echo rsync ${SYNC_OPTIONS} ${SYNC_EXCLUDE} /src/ /dst/
set -x
rsync ${SYNC_OPTIONS} ${SYNC_EXCLUDE} /src/ /dst/
set +x

Which produces:

$ echo rsync ${SYNC_OPTIONS} ${SYNC_EXCLUDE} /src/ /dst/
rsync -a --progress --delete --delete-before --delete-excluded --exclude='some/dir/with spaces/requiring quoting' --exclude='another/dir/with spaces' --exclude='blah blah/blah' /src/ /dst/
$ set -x
$ rsync ${SYNC_OPTIONS} ${SYNC_EXCLUDE} /src/ /dst/
+ rsync -a --progress --delete --delete-before --delete-excluded '--exclude='\''some/dir/with' spaces/requiring 'quoting'\''' '--exclude='\''another/dir/with' 'spaces'\''' '--exclude='\''blah' 'blah/blah'\''' /src/ /dst/
rsync: change_dir "/spaces" failed: No such file or directory (2)
rsync: link_stat "/quoting'" failed: No such file or directory (2)
rsync: link_stat "/spaces'" failed: No such file or directory (2)
rsync: change_dir "/blah" failed: No such file or directory (2)

Both the tracing output and the rsync error messages indicate that there is some extra, unwanted level of tokenizing, which is breaking the usage of the variable in the rsync command. However, the echo command's output looks correct.

How can I define a multi-line variable, which will be used as an argument for the rsync command, where the argument contains quoted file paths with spaces? Specifically, I'm interested in the above case for the SYNC_EXCLUDE variable.

Trevor
  • 1,613
  • 3
  • 22
  • 34
  • Possible duplicate of [this](https://stackoverflow.com/questions/12136948/why-does-shell-ignore-quotes-in-arguments-passed-to-it-through-variables), [this](https://stackoverflow.com/questions/29527983/why-do-bash-parameter-expansions-cause-an-rsync-command-to-operate-differently), and [this](https://stackoverflow.com/questions/22030280/rsync-syntax-error-when-run-from-bash-script). – Gordon Davisson Jan 11 '20 at 18:59

1 Answers1

3

Finally found answer embedded in lengthy, but good answer here. For my case, I converted the variable to array of strings, instead of a single long string, like so:

SYNC_OPTIONS="-a --progress --delete --delete-before --delete-excluded"
SYNC_EXCLUDE=(
    --exclude='some/dir/with spaces/requiring quoting'
    --exclude='another/dir/with spaces'
    --exclude='blah blah/blah'
    )
echo rsync ${SYNC_OPTIONS} "${SYNC_EXCLUDE[@]}" /src/ /dst/
set -x
rsync ${SYNC_OPTIONS} "${SYNC_EXCLUDE[@]}" /src/ /dst/
set +x
Trevor
  • 1,613
  • 3
  • 22
  • 34