bash 用于存储带空格的目录名称的变量
bash variable to store directory names with spaces
我正在编写一个 bash 脚本来收集一些目录(满足条件的目录)和 rsync
那些到远程位置的目录。总体而言,脚本如下所示;
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
请注意,我使用 printf %q
来转义目录名称中的空格。
但是当目录名中有空格时,例如"/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]
如果我只是通过将最后一行更改为
来打印 rsync 命令
echo rsync -vrz $sources /remote/target/
看起来还不错。
(at /home/u/) $ bash script.sh
rsync -vrz /somewhere/dirname /somewhere/dir\ name /remote/target
但是使用 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]
我也尝试使用双引号目录名而不是 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]
一些参数周围的单引号来自哪里?在单行变量中收集带空格的目录以用作 cp
、mv
或 mv
中的源的最佳方法是什么rsync
?
改用数组。
sources=()
for d in /somewhere/* ; do
if $d meets condition; then
sources+=("$d")
fi
done
if [ "${sources[*]}" ]; then
rsync -vrz "${sources[@]}" /remote/target/
fi
使用 set -x
输出的单引号只是为了消除歧义,因此您可以准确地看到实际文字空间的位置(与作为参数分隔符的语法空间相反)。
我正在编写一个 bash 脚本来收集一些目录(满足条件的目录)和 rsync
那些到远程位置的目录。总体而言,脚本如下所示;
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
请注意,我使用 printf %q
来转义目录名称中的空格。
但是当目录名中有空格时,例如"/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]
如果我只是通过将最后一行更改为
来打印 rsync 命令echo rsync -vrz $sources /remote/target/
看起来还不错。
(at /home/u/) $ bash script.sh
rsync -vrz /somewhere/dirname /somewhere/dir\ name /remote/target
但是使用 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]
我也尝试使用双引号目录名而不是 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]
一些参数周围的单引号来自哪里?在单行变量中收集带空格的目录以用作 cp
、mv
或 mv
中的源的最佳方法是什么rsync
?
改用数组。
sources=()
for d in /somewhere/* ; do
if $d meets condition; then
sources+=("$d")
fi
done
if [ "${sources[*]}" ]; then
rsync -vrz "${sources[@]}" /remote/target/
fi
使用 set -x
输出的单引号只是为了消除歧义,因此您可以准确地看到实际文字空间的位置(与作为参数分隔符的语法空间相反)。