【发布时间】:2016-12-23 13:40:13
【问题描述】:
我正在使用 bash 脚本通过 rsync 同步 Web 文件夹。我正在使用要排除的文件夹和文件数组,并且在为排除列表转义这些项目时遇到问题...
我的排除列表是这样定义的......
SYNC_EXCLUSIONS=(
'/exclude_folder_1'
'/exclude_folder_2'
'.git*'
'.svn'
)
然后我像这样构建我的排除字符串......
exclusions='';
for e in "${SYNC_EXCLUSIONS[@]}"
do
exclusions+=" --exclude='$e'";
done
最后我执行了我的 rsync...
rsync --recursive --delete $exclusions "$DEPLOYMENT_WORK_DIR/" "$DEPLOYMENT_ROOT/"
如果我回显该命令,它看起来很完美,如果我在提示符下复制并执行它,它可以正常工作。但是,当从脚本运行时,排除项将被忽略。
我发现如果我从每个排除项目周围删除单引号,它会起作用,就像这样......
exclusions+=" --exclude=$e";
我不希望这样做,以防我需要排除带有空格或特殊字符的文件夹。
有什么方法可以让脚本在保留排除项目周围的引号的同时使其工作?我尝试了各种引号和反斜杠等的组合,但我尝试过的都没有。
【问题讨论】:
-
顺便说一句,为您自己的变量使用全大写名称是不好的形式。请参阅POSIX guidelines on environment variable names(第 4 段),指定 shell 和系统使用全大写名称的变量,应用程序可以使用其他名称的变量而不会发生冲突;因为 shell 变量共享一个命名空间(使用环境变量的名称设置 shell 变量会覆盖后者),这些约定也适用于 shell 变量。
-
谢谢,我不知道这一点。这是我在其他各种语言中使用的约定,表示某些东西是不变的。我没有意识到这不是 bash 的好习惯。我将更改我的代码。
-
公平地说,这是一个没有像应有的那样经常遵循的约定——但它是黑字 POSIX,可以让人们远离麻烦 (比如无意中运行了
for PATH in */; do ...,并拥有一个无法再执行外部程序的解释器。