I'm sure it's completely clear from the subject 🙂 Joking aside, I think part of the problem I'm having finding an answer is writing the search terms.
I have had good luck when issuing commands in a bash script by using an array for the arguments.
For example, I'm calling rsync and created an array like (spolier alert – superfluous variables will be referenced later):
#!/usr/bin/env bash
set -euo pipefail
rf=.rsync-filter
srcff="/home/roger/home$rf"
hm=/home/roger
syncto=/tmp/to-remote/home
rsarg=(-avv --prune-empty-dirs --stats)
rsarg+=(--dry-run)
rsync "${rsarg[@]}" "$hm" "$syncto/" #works
exit
Where I'm having problems is in adding the $srcff variable to a filter rule and adding that to the rsarg array.
rsarg+=("--filter='merge $srcff'") # no dice
# or this
rsarg+=("--filter='merge ${srcff}'") # sad trombone
Upon running I get:
$ ./home-sync-simple
Unknown filter rule: `'merge /home/roger/home.rsync-filter''
rsync error: syntax or usage error (code 1) at exclude.c(904) [client=3.1.1]
I can get it to work by adding the merge rule to the rsync line, outside of the array and minus embedded variable:
rsync "${rsarg[@]}" --filter='merge /home/roger/home.rsync-filter' "$hm" "$syncto/"
Replacing the above filter with the variable outside the array, fails in the same manner:
rsync "${rsarg[@]}" "--filter='merge $srcff'" "$hm" "$syncto/"
I have tried many other variations, I'm assuming all possible excepting the one that actually works. Sometimes it results in "unexpected end of filter rule: merge" and other things. I've excluded those for brevity and because I think the versions above are closer to correct (he said, nervously). I am guessing I end up passing too few/many arguments.
Thanks in advance!
Best Answer
If this works:
Then I suppose you do not want to give the single-quotes to
rsync
. Here, the shell eats them beforersync
sees them. Your other examples have quotes within quotes, so the inner ones stay and are passed forrsync
to see.So skip the single-quotes when building the array:
Note that from the shell's point of view, the equal sign is nothing special, and there's no need to treat the part that comes after any differently than the part before.
--foo=bar
is the same as--foo="bar"
or"--foo=bar"
, or even--fo"o=ba"r
.