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


rsarg=(-avv --prune-empty-dirs --stats)

rsync "${rsarg[@]}" "$hm" "$syncto/"  #works


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!


If this works:

rsync "${rsarg[@]}" --filter='merge /home/roger/home.rsync-filter' ...

Then I suppose you do not want to give the single-quotes to rsync. Here, the shell eats them before rsync sees them. Your other examples have quotes within quotes, so the inner ones stay and are passed for rsync to see.

So skip the single-quotes when building the array:

rsarg+=("--filter=merge $srcff")

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.

  • That's it! Thank you. I was thinking no single quotes would split it into multiple parameters ala the initial assignment rsarg=(-avv --prune-empty-dirs --stats). But I am remem-guessing the double-quotes keep it singular as it would in a regular variable. – roger Apr 3 '17 at 2:51

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.