Skip to content
Advertisement

Using an environment variable in an rsync argument (dealing with quotes and escape character)

I want to use rsync with an –exclude command that looks like

rsync -av --exclude={"*.ext1","*.ext2", "*.ext3"} source target 

(For some reason it is more handy to me to use such a syntax than using the –exclude-from=FILE syntax)

I would like to use an environement variable with rsync so that I could do

export toto='{"*.ext1","*.ext2", "*.ext3"}'
rsync -av --exclude=$toto source target 

The problem is that it doesn’t work the way I wish. When I use the automatic completion over the $toto variable it shows :

{"*.ext1","*.ext2", "*.ext3"} 

It is actually what rsync understands and it gets totally confused.

Could anybody explain the rational behind this “quotes and escape characters” behavior?

Advertisement

Answer

This works:

MYEXCLUDE={'*.ext1','*.ext2'}
eval rsync -av --exclude=$MYEXCLUDE src dest

As already mentioned, {,} triggers brace expansion (btw, the space before ext3 in your example is a problem: it prevents brace exp). And rsync’s exclude option only accepts a single pattern (this means that everything can be understood by replacing rsync and echo).

By chance, when the 1st line sets the variable, brace expansion does not yet take place (echo $MYEXCLUDE shows : {*.ext1,*.ext2}). And brace expansion happens after variable expansion. So the trick is to use eval to have the expansion just-in-time. To fully understand, compare the following 2 lines:

MYEXCLUDE=--exclude={'*.ext1','*.ext2'}
echo $MYEXCLUDE
eval echo $MYEXCLUDE

displays

--exclude={*.ext1,*.ext2}
--exclude=*.ext1 --exclude=*.ext2
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement