脚本:
#!/bin/bash
site=$1
remote_host=$2
new_site=${3:-$1}
cmd="rsync -rlpuvz -e ssh /www/$site/ $remote_host:/www/$new_site --force --delete --exclude=\"site/web_sitemap_*.xml.gz\""
echo $cmd
$cmd
脚本输出:
[xxx@xxx ~]$ rsync -rlpuvz -e ssh /www/xxx/ xxx:/www/xxx --force --delete --exclude="site/web_sitemap_*.xml.gz"
sending incremental file list
deleting site/web_sitemap_ff3abe06_000.xml.gz
它似乎将引号\"
视为文字"
文件名/模式字符。我用单引号(未转义)得到'
与"--exclude='site/web_sitemap_*.xml.gz'"
. 但是,如果我们在没有任何类型的嵌入式引号的情况下尝试相同的事情,它就可以工作!未引用版本:
[xxx@xxx ~]$ touch /www/xxx/site/web_sitemap_ff3abe06_000.xml.gz
[xxx@xxx ~]$ rsync -rlpuvz -e ssh /www/xxx/ xxx:/www/xxx --force --delete --exclude=site/web_sitemap_*.xml.gz
sending incremental file list
sent 41624 bytes received 290 bytes 7620.73 bytes/sec
total size is 18233892 speedup is 435.03
:
不使用引号似乎是答案,但是如果 rsync 排除模式包含通常会被 bash 扩展或解释的符号(如or;
或\
or ) ,我该如何防止 shell 扩展或解释特殊字符[
?
您应该阅读BashFAQ/050 aka 我正在尝试将命令放入变量中,但复杂的情况总是失败!.
一个 TL;DR:
尝试将命令存储在变量中时,分词也是一个问题。尽管不是您的直接示例,但这是必须注意的。
阅读
#050
后,您可以重新评估是否真的需要这样做。如果您仍然认为您这样做并选择忽略针对它的建议,您将希望将您的命令存储在一个数组中: