Search code examples
bashrsync

execute command from shell script fails


When I run my script it fails:

# sh -x ./rsync.sh 
...
+ rsync --safe-links --password-file=/etc/rsync.secret -rtvun --include='*.log*.gz' --filter='-! */' --prune-empty-dirs /some/path foo@hostname::foo
Unknown filter rule: `'-!'
rsync error: syntax or usage error (code 1) at exclude.c(904) [client=3.1.1]

but when I copy&paste the rsync --safe-links .... line and execute it it works fine.

rsync.sh:

#!/bin/bash

rsync_opts="--safe-links --password-file=/etc/rsync.secret -rtvu"

while read path hostname volume extra_opts; do
  rsync ${rsync_opts} ${extra_opts} ${path} ${volume}@${hostname}::${volume}
done < /etc/rsync.paths

rsync.paths:

/some/path/ hostname foo --include='*.log*.gz' --filter='-! */' --prune-empty-dirs

Does anyone knows why it fails from the script and works fine when I run the command manually ? How can I fix it ?

UPDATE: It works fine when I use eval "rsync ..." but still I don't know why it doesn't work withou it :/


Solution

  • Your problem is that your script reads the text --filter='-! */' --prune-empty-dirs into the variable $extra_opts, which is passed literally to the command, including the apostrophes. So it is split into the following arguments: --filter='-!, */' and --prune-empty-dirs. When you eval it though, then the whole line is passed to the shell interpreter which interprets the apostrophes the way you want, that's why it works.

    Also, since your script uses bash, you should debug it with bash -x instead of sh -x.