我可以通过ssh获取子shell中执行的命令的退出代码吗?

时间:2011-03-17 16:51:54

标签: ssh paramiko

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

问题在于,根据我的理解,我有3个子shell - ssh会话,嵌套的ssh命令,然后是su subshel​​l。我不能让Paramiko给我回到内部子shell中命令的退出代码 - 我猜它最终将返回的退出代码将是ssh命令的退出代码。我怀疑这个问题实际上并不是Paramiko特有的 - SSH协议是否支持这种用法?

我目前一直在执行:

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

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

2 个答案:

答案 0 :(得分:8)

  

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

是的,不。

始终返回退出状态,但可能不是您所想的位置。一旦你调用invoke_shell(),你的远程进程就是一个shell,可能是bash。您收到的exit_status将是该shell的一个,它运行的任何进程。 Paramiko(也没有任何ssh实现)可以返回命令的退出状态,因为在远程shell之外永远不会看到退出状态。您需要确定退出状态应该是什么,并使用exit $EXIT_STATUS退出shell(通常exit $?已足够)

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

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

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

答案 1 :(得分: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

宾果。 “退出3”正在变成“退出”,然后是一个被忽略的单词 在bash命令行上。所以bash正在运行命令“exit”。

对我来说不幸的是,我觉得整个答案都是一个题外话 从原始问题,并没有足够的功绩 一个问题本身就是一个问题。所以感谢大家帮助我 通过次要问题回答(与原始问题无关)。