6

我正在尝试使用 Paramiko 编写部署脚本,但我在运行命令的退出代码时遇到了问题。我正在使用与此答案中的代码类似的代码,但它有点复杂。基本上,从我们的开发盒中,我们必须经过一个跳转服务器,然后从那里到一系列生产机器。在那里,我们必须切换到系统用户(sudo su - systemuser),然后我们才能运行命令。

问题是,据我了解,我有 3 个子外壳 - ssh 会话、嵌套的 ssh 命令,然后是 su 子外壳。我无法让 Paramiko 将内部子 shell 中命令的退出代码返回给我——我猜它最终返回的退出代码将是 ssh 命令的退出代码。我怀疑这个问题实际上并不是 Paramiko 特有的——SSH 协议甚至支持这种用法吗?

我目前一直在执行:

(my command); echo "Process terminated with exit code $?"

然后在客户端上解析它,但它非常难看 - 有更好的方法吗?

4

2 回答 2

8

我猜它最终将返回的退出代码将是 ssh 命令的退出代码。我怀疑这个问题实际上并不是 Paramiko 特有的——SSH 协议甚至支持这种用法吗?

是的,没有。

退出状态总是返回,但可能不是你想的地方。一旦你调用invoke_shell(),你的远程进程就是一个 shell,可能是 bash。您收到的exit_status将是来自该 shell 的那个,而不是它运行的任何进程。Paramiko(也不是任何 ssh 实现)永远不会返回命令的退出状态,因为退出状态永远不会在远程 shell 之外看到。由您决定退出状态应该是什么,然后退出 shell exit $EXIT_STATUS(通常exit $?就足够了)

如果您可以分解您的命令,或将它们包装在脚本中,然后使用该exec_command()方法,您将可以直接访问正确的退出状态。

或者,您可以exec在远程shell中使用shell命令,shell的进程将被exec调用的命令替换,并返回其退出状态。

所有这三种方法都channel.exit_status将按预期设置属性。

于 2011-03-29T18:01:18.640 回答
2

我有一个问题,'ssh' 的手册页说它返回它运行的进程的退出代码,但我似乎无法让它返回一个非零错误代码。从 ssh 手册页:

 The session terminates when the command or shell on the remote machine
 exits and all X11 and TCP/IP connections have been closed.  The exit sta‐
 tus of the remote program is returned as the exit status of ssh.

这似乎不是真的。

但我会尝试这样的事情,看看你的系统会发生什么。

% ssh localhost bash -c "exit 3" ; echo $?
0

当我在本地运行类似的命令时,bash 返回一个退出代码。

% bash -c 'exit 3' ; echo $?
3

然而,在 ssh 出现命令之前,双引号将被删除。所以让我们尝试更多的报价。

% ssh localhost bash -c "'exit 3'" ; echo $?
3

答对了。在 bash 命令行上,“exit 3”变成了“exit”,后面跟着一个被忽略的单词。所以 bash 正在运行命令“exit”。

对我来说不幸的是,我认为整个答案是对原始问题的题外话,并且作为一个问题本身并没有足够的价值。所以感谢大家帮助我回答次要问题(与原始问题无关)。

于 2011-03-17T22:37:27.383 回答