[英]bash variable to store directory names with spaces
I'm writing a bash script to collect some directories (where conditions are met) and rsync
those to a remote location.我正在编写一个 bash 脚本来收集一些目录(满足条件的地方)并将它们
rsync
到远程位置。 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.请注意,我使用
printf %q
来转义目录名称中的空格。 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;但是当目录名中有空格时,例如
"/somewhere/dir name"
满足条件时,rsync认为是两个目录而无法运行;
(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如果我只是通过将最后一行更改为来打印 rsync 命令
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.但是使用
set -x
显示了一些古怪的事情。
(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.我也尝试使用双引号目录名而不是
printf %q
但它也不起作用,原因略有不同。
(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
?那些围绕某些参数的单引号来自哪里,在单行变量中收集带有空格的目录以用作
cp
、 mv
或rsync
源的最佳方法是什么?
Use an array instead.改用数组。
sources=()
for d in /somewhere/* ; do
if $d meets condition; then
sources+=("$d")
fi
done
if [ "${sources[*]}" ]; then
rsync -vrz "${sources[@]}" /remote/target/
fi
The single quotes output with set -x
are just for disambiguation, so you can see exactly where actual literal spaces go (as opposed to syntactic spaces which are argument separators).使用
set -x
输出的单引号只是为了消除歧义,因此您可以准确地看到实际文字空间的位置(与作为参数分隔符的语法空间相反)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.