这为什么不起作用?
$ ssh vm "bullshitcommand; echo $?"
bash: bullshitcommand: command not found
0
我期望非零返回码。
答案1
原因:
echo $?
,你实际上是在发送一个局部变量$?
并要求在 ssh shell 中回显它,看起来是这样。你可以在 ssh 语句前使用不存在的命令来证明这一点。例如:
notexistingcommand; ssh vm "echo $?"
输出
bash:不存在的命令:未找到命令
127
甚至
export var=123; ssh vm "echo $var"
输出
123
解决方案:
要使用远程变量,您可以执行转义,它将输出 -1(或 127):
ssh vm "nonexistentcmd; echo \$?"
或者您可以使用单引号 (‘) 因为它们不扩展变量并且按字面意思理解 $ 符号
ssh vm 'nonexistentcmd; echo $?'
答案2
不要说:
ssh vm "bullshitcommand; echo $?"
说:
ssh vm "bullshitcommand"
echo $?
返回代码ssh
将与远程命令的返回代码相同。
答案3
你说,这不起作用:
$ ssh vm "bullshitcommand; echo $?"
bash: bullshitcommand: command not found
0
首先我们来分析一下人物:
"not important $? not important"
在客户端本地解释,而不是在服务器上这将被解释为:
"not important 0 not important"
因为客户端(本地)特殊变量 $? 通常为 0。为了防止这种情况,您应该进行转义,因为您希望将文本 $? 按原样放置而不进行替换:
"not important \$? not important"
另一个问题是你做了什么。你只是丢失了你感兴趣的退出代码。让我们看下面的例子:
$ ssh vm "bullshitcommand; echo external ret: \$?"; echo internal ret: $?
bash: bullshitcommand: command not found
external ret: 127
internal ret: 0
发生了什么?外部 $? 截取退出代码,然后一步之后,您将获得 echo 命令的退出代码。这始终是 0,因为 echo 不可能崩溃 :) 最后 ssh 服务器从最后一个命令获取退出代码,它是从 echo 获得的,为 0。之后 ssh 客户端给出 0 代码。最后这导致 ssh 命令以 0 退出。
您可以通过临时保存 $? 值来解决此问题,例如:
$ ssh vm "bullshitcommand; exitcode=\$? echo external ret: \$exitcode; exit \$exitcode"; echo internal ret: $?
bash: bullshitcommand: command not found
external ret: 127
internal ret: 127
当你收到结果时,你就到家了 :)。问题是,exitstatus 是不持久的,上面有解决办法。记住退出 :)
但请注意历史上损坏的 ssh 服务器和客户端。有时服务器和/或客户端会忽略退出状态并永久返回 0 返回代码。如果必须确定,请测试它。如果遇到这种情况,您应该升级软件,或者通过 stdout 流传输退出代码来采取一些解决方法。对于编写它的脚本和程序员来说,这是额外的工作。