The shell parses quotes before expanding variables, so putting quotes in a variable’s value doesn’t do what you expect — by the time they’re in place, it’s too late for them to do anything useful. See BashFAQ #50: I’m trying to put a command in a variable, but the complex cases always fail! for more details.
In your case, it looks like the easiest way around this problem is to use an array rather than a plain text variable. This way, the quotes get parsed when the array is created, each “word” gets stored as a separate array element, and if you reference the variable properly (with double-quotes and [@]
), the array elements get included in the command’s argument list without any unwanted parsing:
filter=(--include="lib/***" --include="arm-none-eabi/include/***" \
--include="arm-none-eabi/lib/***" --include="*/" --exclude="*")
rsync -amnv "${filter[@]}" /tmp/from/ /tmp/to/
Note that arrays are available in bash and zsh, but not all other POSIX-compatible shells. Also, I lowercased the filter
variable name — recommended practice to avoid colliding with the shell’s special variables (which are all uppercase).