Bash rsync 脚本出错

Bash rsync 脚本出错

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 的复杂程度:

  1. 如果 --rsh 是 OPTS 中唯一的东西,那么就用双引号引起来(就像 Dennis Williamson 的回答一样):

    OPTS='--rsh=ssh -p2222'
    rsync "$OPTS" "$BACKDIR" "$USER@$DEST:$DESTDIR"
    

    (还请注意其他参数周围的双引号:这是为了防止如果它们包含空格则发生错误解析,并且通常是一种良好的脚本卫生习惯。)

  2. 如果 OPTS 的内容是常量(或者至少 --rsh 部分是常量),那么不要尝试将其放入变量中,直接使用它即可:

    rsync --rsh='ssh -p2222' $RESTOFOPTS "$BACKDIR" "$USER@$DEST:$DESTDIR"
    
  3. 如果这两种简单情况都不适用,请使用数组而不是普通变量:

    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 的行为将符合大多数程序员的期望,因为空格不再用作变量内的字段分隔符。

相关内容