I'm writing a bash script to collect some directories (where conditions are met) and rsync
those to a remote location. Overall the script looks like this;
sources=""
for d in /somewhere/* ; do
if $d meets condition; then
sources="$sources $(printf %q "$d")"
fi
done
if [ ! -z $sources ] ; then
rsync -vrz $sources /remote/target/
fi
Note that I'm using printf %q
to escape spaces in directory names.
However when there are spaces in directory names, for example when "/somewhere/dir name"
met the condition, the rsync thinks that as two directories and fails to run;
(at /home/u/) $ bash script.sh
sending incremental file list
rsync: link_stat "/somewhere/dir\" failed: No such file or directory (2)
rsync: link_stat "/home/u/name" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1196) [sender=3.1.2]
If I just print the rsync command by changing the last line to
echo rsync -vrz $sources /remote/target/
it looks just fine.
(at /home/u/) $ bash script.sh
rsync -vrz /somewhere/dirname /somewhere/dir\ name /remote/target
But using set -x
shows something wacky going on.
(at /home/u/) $ bash script.sh
+ rsync -vrz /somewhere/dirname '/somewhere/dir\' name /remote/target
sending incremental file list
rsync: link_stat "/somewhere/dir\" failed: No such file or directory (2)
rsync: link_stat "/home/u/name" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1196) [sender=3.1.2]
I also tried to use double quoted directory names instead of printf %q
but it didn't work either, with a slightly different reason.
(at /home/u/) $ bash script.sh
+ rsync -vrz '"/somewhere/dirname"' '"/somewhere/dir' 'name"' /remote/target
sending incremental file list
rsync: change_dir "/home/u//"/somewhere" failed: No such file or directory (2)
rsync: change_dir "/home/u//"/somewhere" failed: No such file or directory (2)
rsync: link_stat "/home/u/name"" failed: No such file or directory (2)
sent 20 bytes received 12 bytes 64.00 bytes/sec
total size is 0 speedup is 0.00
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1196) [sender=3.1.2]
Where are those single quotes around some arguments coming from and what is the best way to collect directories with spaces in a single-lined variable for using as sources in cp
, mv
, or rsync
?