运行远程脚本的意外行为

Posted

技术标签:

【中文标题】运行远程脚本的意外行为【英文标题】: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。

【问题讨论】:

【参考方案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 次。 至少,这对我来说是这样的

....

【讨论】:

以上是关于运行远程脚本的意外行为的主要内容,如果未能解决你的问题,请参考以下文章

意外的异步行为:Springs 的 @Async 与 RxJava

尝试在python子进程中运行rsync时出现意外的远程arg错误

Git 克隆失败 - 致命:远程端意外挂断。致命:早期 EOF 致命:索引包失败

使用 ajax() 和 jsonp 调用 asp.net 远程 Web 服务 .asmx 时出现意外令牌 <

VPS服务器上运行脚本,在本地断开远程桌面后脚本失效

如何使用SSH在远程计算机上运行shell脚本?