0
votes

I've spent dozen man hours were trying to understand why rsync ignores options --exclude being running in script in spite of the same command were perfectly working from command line.

Bash-script (a part of): EXCEPTIONS="$EXCEPTIONS --exclude=$ex" - fills-in variable with list of excludes, reading from file in loop. And this is how rsync is run: rsync -aus --no-verbose $EXCEPTIONS "$SOURCEDIR/$backup_path/" "$SYNCTODIR/$backup_path"

It works. Finally.

BUT. If you try to use quotes in excludes, like this: EXCEPTIONS="$EXCEPTIONS --exclude='$ex'" or like this: EXCEPTIONS="$EXCEPTIONS --exclude=\"$ex\"" you'll get the situation when rsync is run with --exclude parameters but it don't care on what you wrote as a value in them - it will merely ignore excludes. At the same time, there is no difference between using or not quotes in SOURCE and DESTINATION.

And yes, it works if you run rsync from shell (not in script) and use or not quotes in --exclude. I think the same situation is with other parameters.

I'd be very appreciated if someone could explain such behavior. Thank you.

UPDATE1: Thank you, Jetchisel, I've read about word splitting but let's takle a look at how it works. Two scripts:

#!/bin/bash
echo $IFS
printf "%d args:" "$#"
printf " <%s>" "$@"
echo

and

#!/bin/bash
./test.sh  -arqu --exclude 'dshul' --exclude 'RegressionTest' --exclude 'builds' odashare2/QA/ share/QA
./test.sh  -arqu --exclude='dshul' --exclude='RegressionTest' --exclude='builds' "odashare2/QA/" "share/QA"

The second just run first one with parameters. And now outcome of running of these scripts:


6 args: <-arqu> <--exclude=dshul> <--exclude=RegressionTest> <--exclude=builds> <odashare2/QA/> <share/QA>
admin@odastorage2:~$ ./test.sh  -arqu --exclude='dshul' --exclude='RegressionTest' --exclude='builds' "odashare2/QA/" "share/QA"

6 args: <-arqu> <--exclude=dshul> <--exclude=RegressionTest> <--exclude=builds> <odashare2/QA/> <share/QA>
admin@odastorage2:~$ ./test.sh  -arqu --exclude 'dshul' --exclude 'RegressionTest' --exclude 'builds' odashare2/QA/ share/QA

9 args: <-arqu> <--exclude> <dshul> <--exclude> <RegressionTest> <--exclude> <builds> <odashare2/QA/> <share/QA>
admin@odastorage2:~$
admin@odastorage2:~$
admin@odastorage2:~$ ./testar.sh

9 args: <-arqu> <--exclude> <dshul> <--exclude> <RegressionTest> <--exclude> <builds> <odashare2/QA/> <share/QA>

6 args: <-arqu> <--exclude=dshul> <--exclude=RegressionTest> <--exclude=builds> <odashare2/QA/> <share/QA>

Looks reasonable and clear. So I still don't understand what's wrong with rsync.

1
Unquoted variables works because you're relying on word-splitting see Understanding word splitting . The short answer is to use an array.Jetchisel
I've read it, thank you. But the question is still actual: it doesn't work as well in case if I don't use "=" between --exclude and name of exclude (its value). Besides, IFC is not set or set to default [ \t\n] - ok, then any IFC symbols can be used as delimiters. What are these ANY IFS symbols?wsdx
Sorry, typo: not IFC - IFS.wsdx
Putting complex arguments in a variable (like, anything that needs quotes) doesn't work the way you expect; use an array instead. See my answer to this question, and also this question, and BashFAQ #50: I'm trying to put a command in a variable, but the complex cases always fail!Gordon Davisson
Hello Gordon, thank you - I'll see. Besides, I've found the other solution - will post that as the answer on post.wsdx

1 Answers

0
votes

Found the other solution here: https://askubuntu.com/questions/1235412/rsync-wont-exclude-folders-passed-as-a-variable-in-a-script/1235448#1235448 :

#!/bin/bash

declare -a excludes

echo "Type the path of the folders to exclude: "
while IFS= read -r folder
do
    excludes+=( --exclude="$folder" )
done

rsync -n -avh "${excludes[@]}" -- source/ destination/

Gordon, now I understand it all. Thank you.