【问题标题】:Unexpected behaviour running remote script运行远程脚本的意外行为
【发布时间】:2019-04-23 19:25:49
【问题描述】:

我正在尝试编写一个在远程机器上运行的脚本。

由于这个脚本很复杂,我将它的一部分分解为函数,然后使用typeset 复制到脚本中。

当我运行脚本时,我收到以下错误:

bash: -c: line 4: syntax error: unexpected end of file

但是,文件没有意外结束!我确保所有ifs 都有fis,所有{ 都有},等等。

我已确保所有缩进都使用制表符(和空格),并确保换行符一致。

我已将代码精简为一个最小示例。似乎要使函数有效,它需要以 if fiwhile done 之类的结构结尾。

这就是不工作的地方。

func() {
  ls ~/
}

ssh -A -T user@machine_ip '
'$(typeset -f func)'
func
'

第 4 行与 func 函数的结尾 } 重合(从 ssh -A -T... 之后开始计数行,因为此错误发生在远程计算机上)。

然而,如果我们在函数末尾添加一个构造,则主目录会按预期打印。

func() {
    ls ~/
    if [[ 1 ]]; then
      echo "Hello"
    fi
}

func() {
    ls ~/
    while false; do
        echo "Here"
    done
}

typeset -f func 的输出是

func () 
{ 
    ls --color=auto ~/;
    if [[ -n 1 ]]; then
        echo "Hello";
    fi
}

我运行的是 Ubuntu 18.04 LTS,远程机器运行的是 Centos 6。

【问题讨论】:

    标签: linux bash shell ssh centos6


    【解决方案1】:

    因为 bash 会在允许时使用空格。让我解释一下:

    $(typeset -f func) 将评估typeset -f func 并将其输出插入当前命令行。如果没有引用,它还将分段为参数,这将作为副作用将所有空格折叠为单个空格。因此,如果 typeset -f func 打印(就像在我的系统上一样)

    func () 
    { 
        /bin/ls --color=auto ~/
    }
    

    $(typeset -f func) 得到的是

    func () { /bin/ls --color=auto ~/ }
    

    (如果你不相信我,试试echo $(typeset -f func) :D)

    现在,bash 对于接受被弄乱的代码真的很害羞。例如,您可能知道这不符合语法:

    if true then echo "yes" fi
    

    这是:

    if true; then echo "yes"; fi
    

    同样,函数定义的右括号也很挑剔。因此,这是可行的:

    func () { /bin/ls --color=auto ~/; }
    

    但这不是:

    func () { /bin/ls --color=auto ~/ }
    

    出于某种原因,bash 可以在括号前加上关键字:

    func () { /bin/ls --color=auto ~/; if [[ -n 1 ]]; then echo "Hello"; fi }
    func () { /bin/ls --color=auto ~/; while false; do echo "Here"; done }
    

    为了解决这个问题...尽量不要从命令行发送东西,这会破坏你的空白,而是从重定向:

    ssh -A -T user@machine_ip < <(typeset -f func; echo func)
    

    或者,最简单的是,防止 bash 使用双引号对空格进行修饰:

    ssh -A -T user@machine_ip "$(typeset -f func)
    func"
    

    【讨论】:

      【解决方案2】:

      首先,你使用引号的方式对我来说毫无意义。

      ssh -A -T user@machine_ip '
      '$(typeset -f func)'
      func
      '
      

      2 first ' 只是回显一个空行。 (第二个'关闭第一个。逻辑?)

      无论如何。

      $(typeset -f func)
      func
      

      上面的代码将执行 func 2 次。 至少,这对我来说是这样的

      ....

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-12
        • 2010-12-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多