1

I have the following for-loop which loops through all the given sources that need to be copied.

for i in "${sources[@]}"; do
    exclude="--exclude 'exclude_folder/exclude_file'"

    rsync -az $exclude $i $destination
done

However, the exclude option is not working.

for i in "${sources[@]}"; do
    exclude="--exclude 'exclude_folder/exclude_file'"

    rsync -az "$exclude" "$i" "$destination"
done

If I use the code above, rsync will exit and give an error that it is an unknown option.

If I simply use the following code, it works, but I want to use a variable for the exclude option.

for i in "${sources[@]}"; do
    rsync -az --exclude 'exclude_folder/exclude_file' $i $destination
done

2 Answers2

0

I would use eval.

Your code:

for i in "${sources[@]}"; do
    exclude="--exclude 'exclude_folder/exclude_file'"

    rsync -az "$exclude" "$i" "$destination"
done

would be then (I'm trying to be as close to your logic as possible):

for i in "${sources[@]}"; do
    exclude="--exclude 'exclude_folder/exclude_file'"
    rsync_command="rsync -az $exclude $i $destination"

    eval rsync_command
done

From the eval man pages:

eval

Evaluate several commands/arguments

Syntax eval [arguments]

The arguments are concatenated together into a single command, which is then read and executed, and its exit status returned as the exit status of eval. If there are no arguments or only empty arguments, the return status is zero.

eval is a POSIX `special' builtin

EDIT

Gordon Davisson is right about the bugs/insecurities in eval. If any other solution is available then it is better to use it. Here the bash arrays are better. The array answer is superior answer.

Please see the answer at Bash: need help passing a a variable to rsync

tukan
  • 17,050
  • 1
  • 20
  • 48
  • Please to **not** use `eval` -- it has a well-deserved reputation as a source of obscure and incomprehensible bugs. Arrays are a much better way to handle this; see the linked duplicate for details. – Gordon Davisson Jun 09 '18 at 17:40
  • @GordonDavisson you are right about the bugs (insecurities). I'll link the proposed duplicate. – tukan Jun 09 '18 at 18:08
  • 1
    It's not just insecurities (i.e. vulnerability to *intentional* attacks); in a comment [here](https://stackoverflow.com/questions/26554819/bash-strings-commands-and-escaping-oh-my/26554864#comment41731531_26554864), Charles Duffy says he's "seen glob expansion result in multiple TB of backups being unexpectedly deleted after a buffer overflow dumped garbage (including a whitespace-surrounded wildcard) into a filename in a directory that was otherwise considered certain to only have names matching `[A-Za-z0-9]+`". Shouldn't be a risk here (`--delete-excluded` is not supplied), but still... – Gordon Davisson Jun 09 '18 at 20:09
0

Example list directories to exclude (also wildcharts) :

#!/bin/sh
export PATH=/usr/local/bin:/usr/bin:/bin
LIST="rootfs usr data data2"
for d in $LIST; do
rsync -az --exclude /$d/ .....
done