运行远程脚本的意外行为
Posted
技术标签:
【中文标题】运行远程脚本的意外行为【英文标题】:Unexpected behaviour running remote script 【发布时间】:2019-04-23 19:25:49 【问题描述】:我正在尝试编写一个在远程机器上运行的脚本。
由于这个脚本很复杂,我将它的一部分分解为函数,然后使用typeset
复制到脚本中。
当我运行脚本时,我收到以下错误:
bash: -c: line 4: syntax error: unexpected end of file
但是,文件没有意外结束!我确保所有if
s 都有fi
s,所有 都有
,等等。
我已确保所有缩进都使用制表符(和空格),并确保换行符一致。
我已将代码精简为一个最小示例。似乎要使函数有效,它需要以 if
fi
或 while
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 致命:索引包失败