I'm writing a script that uses rsync and excludes files based on certain settings. I end up with an exclude flag that has a format of --exclude={foo, bar, baz}.

However, upon trying to expand it within the rsync command, I noticed the flag is escaped. From the bash debugger, I can see my command of rsync $excludes becomes rsync '--exclude={foo,bar,baz}', rather than the expected rsync --exclude={foo,bar,baz}. Doing some testing, I found that any string containing =, {, or } will get wrapped in single quotes when expanded. Short of using eval on a constructed string, is there a way around this?

  • Do you really want it to expand to --exclude={foo,bar,baz} or are you trying to have brace expansion expand it to: --exclude=foo --exclude=bar --exclude=baz?
    – jesse_b
    Jul 4 '18 at 14:35
  • The former is the goal.
    – ollien
    Jul 4 '18 at 14:35
  • I also think that isn't the right syntax. Should be --exclude foo. I don't think rsync takes braces either though.
    – jesse_b
    Jul 4 '18 at 14:36
  • Using the equals sign is the correct syntax.
    – ollien
    Jul 4 '18 at 14:36
  • From the man page, --exclude=PATTERN exclude files matching PATTERN
    – ollien
    Jul 4 '18 at 14:38

Brace expansion won't occur when quoted. You should also store arguments in an array rather than a variable (when possible).

I think the following should work for you:

excludes=( $(--exclude={foo,bar,baz}) )
rsync "${excludes[@]}"
  • This does not work. This expands to rsync '--exclude=foo' '--exclude=bar' '--exclude=baz'
    – ollien
    Jul 4 '18 at 15:03
  • @ollien: That is what you need. --exclude={foo,bar,baz} would be a syntax error to rsync
    – jesse_b
    Jul 4 '18 at 15:07
  • rsync does not recognize the flag when it is prepended by a single quote.
    – ollien
    Jul 4 '18 at 15:09
  • The single quote doesn't actually go to rsync, it will be consumed by the shell
    – jesse_b
    Jul 4 '18 at 15:10
  • 1
    You definitely do not need the echo in there. excl=( --exclude={a,b,c} ) works in bash.
    – Kusalananda
    Jul 8 '18 at 12:24

From the bash debugger, ... any string containing =, {, or } will get wrapped in single quotes when expanded.

If you mean the xtrace output (set -x), it does indeed like to display arguments in single quotes when they contain special characters. The output is in a format that would be usable as input to the shell.

That doesn't mean the quotes are part of the string, though.


$ echo abc def\ ghi
+ echo abc 'def ghi'
abc def ghi

$ echo abc \'def\ ghi\'
+ echo abc ''\''def ghi'\'''
abc 'def ghi'

Though as far as I can see, it doesn't bother to quote strings containing the equal sign.

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.