我用以下内容编写了一个bash脚本:
SRC="dist_serv:$HOME/www/"
DEST="$HOME/www/"
OPTIONS="--exclude 'file.php'"
rsync -Cavz --delete $OPTIONS $SRC $DEST
rsync失败,我无法弄清楚为什么,虽然它似乎与$ OPTIONS变量有关(当我删除它时它会起作用)。我尝试用反斜杠(以及许多其他东西)逃避空间,但这不起作用。 错误消息是:
rsync: mkdir "/home/xxx/~/public_html/" failed: No such file or directory (2)
我尝试引用变量,这会引发另一个错误(我的变量$ OPTIONS上的“未知选项”):
rsync: --exclude 'xxx': unknown option
rsync error: syntax or usage error (code 1) at main.c(1422) [client=3.0.6]
答案 0 :(得分:0)
在为值赋值时,不应将$
放在变量名前面。 SRC
是一个变量,$SRC
是它展开的值。
此外,当您将其放在引号中时,~
不会扩展到主目录的路径。通常最好在脚本中使用$HOME
,因为此变量的行为类似于变量,~
不会这样做。
始终引用变量扩展:
rsync -Cavz --delete "$OPTIONS" "$SRC" "$DEST"
除非有某些理由不(很少有)。 shell会对它们进行分词。
用户@Fred指出您不能在$OPTIONS
周围使用双引号(在下面的评论中),但如果您使用OPTIONS='--exclude="file.php"'
则应该没问题(请注意{{1} }})。
答案 1 :(得分:0)
我发现一种非常有价值的技术是使用位置参数来轻松使用选项列表。
当您在变量(例如OPTIONS
变量)中放置选项时,您需要找到一种在值内包含引号的方法,并在引用变量时省略引号。它可以工作,但是你总是从一个难以调试的失败中解决一个错误。
相反,请尝试以下方法。
set -- -Cavz --delete
set -- "$@" --exclude "file.php"
set -- "$@" "dist_serv:~/www/"
set -- "$@" "~/www/"
rsync "$@"
当然,在这种情况下,所有内容都可以在同一行,但在许多情况下会有条件表达式,例如,您可以省略给定选项,或选择要使用的差异文件。好的方面是,你总是使用在单个命令行中使用的相同引用,这完全归功于"$@"
的魔力,它避免了引用(或引用)任何特定变量。
如果实际位置参数受阻,您可以将它们放在变量中,或者创建一个函数来隔离一个上下文,避免在它们重要的地方触摸它们。
我一直都在使用这个技巧,而且由于引用引起的问题导致我的头发问题,我将其作为参数传递给命令。
使用数组可以实现类似的结果。
declare -a ARGUMENTS=()
ARGUMENTS=(-Cavz --delete )
ARGUMENTS+=(--exclude "file.php")
ARGUMENTS+=("dist_serv:~/www/")
ARGUMENTS+=("~/www/")
rsync "${ARGUMENTS[@]}"