Bash 脚本包含以下行
rsync $OPTS $BACKDIR $USER@$DEST:$DESTDIR
但其中一个选项是rsh='ssh -p2222'
它抱怨:
rsync: -p2222': unknown option
rsync error: syntax or usage error (code 1) at main.c(1425) [client=3.0.7]
但是当我将脚本更改为:
echo rsync $OPTS $BACKDIR $USER@$DEST:$DESTDIR
并手动运行打印的命令,它可以工作。
请指教
答案1
简短回答:参见Bash常见问题解答#50。
长答案:将命令(或命令的一部分)放入变量中,然后完整地取出它们,这很复杂。当 shell 在命令行上扩展变量时,如果变量在双引号中,则不会对其进行解析(请参阅@Dennis Williamson 的答案);如果它不在引号中,则其中的空格将被解析为参数中断,但引号和转义不会被解析(这就是为什么您会收到有关 rsync 的一个参数中的文字引号的错误)。无论哪种情况,将引号放在变量的值中都没有任何用处。
但是,有几种方法可以修复你的脚本,具体取决于 OPTS 的复杂程度:
如果 --rsh 是 OPTS 中唯一的东西,那么就用双引号引起来(就像 Dennis Williamson 的回答一样):
OPTS='--rsh=ssh -p2222' rsync "$OPTS" "$BACKDIR" "$USER@$DEST:$DESTDIR"
(还请注意其他参数周围的双引号:这是为了防止如果它们包含空格则发生错误解析,并且通常是一种良好的脚本卫生习惯。)
如果 OPTS 的内容是常量(或者至少 --rsh 部分是常量),那么不要尝试将其放入变量中,直接使用它即可:
rsync --rsh='ssh -p2222' $RESTOFOPTS "$BACKDIR" "$USER@$DEST:$DESTDIR"
如果这两种简单情况都不适用,请使用数组而不是普通变量:
OPTS=(-x --delete --inplace) if [[ "$rsync_version" == 2.* ]]; then OPTS+=(-aE) else OPTS+=(-aNHX) fi if [[ -n "$using_rsh" ]]; then OPTS+=('--rsh=ssh -p2222') fi rsync "${OPTS[@]}" "$BACKDIR" "$USER@$DEST:$DESTDIR"
答案2
为了保留变量中的引号和空格,需要在引用变量时用引号括起来:
rsync "$OPTS" "$BACKDIR" "$USER@$DEST:$DESTDIR"
答案3
我猜你的选项应该与 rsync 的(resp. ) 标志rsh
一起使用,以便 rsync 知道使用自定义端口进行 ssh 连接。你的命令是否如下所示:-e
--rsh
ssh -some -opts --rsh="ssh -p222" fromdir/ user@host:/todir
可能是 rsync 执行时“ssh -p222”部分周围的引号丢失了。您可以尝试rsh
像这样定义变量:
rsh='"ssh -p222"'
以便它在执行时计算为“ssh -p222”(字面意思,包括双引号)。
答案4
一个选项是从脚本中的 $IFS 中删除“空格”:
#!/bin/bash
IFS=$'\n\t'
...
rsync $OPTS $BACKDIR $USER@$DEST:$DESTDIR
Bash 的行为将符合大多数程序员的期望,因为空格不再用作变量内的字段分隔符。