意外行为 运行 远程脚本

Unexpected behaviour running remote script

我正在尝试编写 运行 远程计算机上的脚本。

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

当我 运行 脚本时,出现以下错误:

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

但是,没有意外的文件结束!我确保所有 if 都有 fi,所有 { 都有 },等等

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

我已将代码简化为一个最小的示例。似乎一个函数要有效,它需要以 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
}

我是 运行ning Ubuntu 18.04 LTS,远程机器是 运行ning Centos 6.

因为 bash 玩白色 space 如果你愿意的话。让我解释一下:

$(typeset -f func) 将计算 typeset -f func 并将其输出插入当前命令行。如果不加引号,它也会分段成参数,这会产生一个副作用,即所有白色 space 折叠成单个 space。因此,如果 typeset -f func 打印(就像在我的系统上一样)

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

你用 $(typeset -f func) 得到的是

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

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

现在,bash 确实 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 }

为了解决这个问题...请尝试不要从命令行发送内容,这会破坏您的白色space,而是通过重定向:

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

或者,最简单的,使用双引号防止 bash 白色 space 的错位:

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

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

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

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

无论如何。

$(typeset -f func)
func

上面的代码会执行func 2次。 至少,这对我有用

.....