我正在尝试使用Paramiko来编写部署脚本,而且我遇到了运行命令的退出代码问题。我使用的代码类似于this answer中的代码,但它有点复杂。基本上,从我们的开发盒中,我们必须通过跳转服务器,从那里到一系列生产机器。在那里,我们必须切换到系统用户(sudo su - systemuser)然后我们可以运行命令。
问题在于,根据我的理解,我有3个子shell - ssh会话,嵌套的ssh命令,然后是su subshell。我不能让Paramiko给我回到内部子shell中命令的退出代码 - 我猜它最终将返回的退出代码将是ssh命令的退出代码。我怀疑这个问题实际上并不是Paramiko特有的 - SSH协议是否支持这种用法?
我目前一直在执行:
(my command); echo "Process terminated with exit code $?"
然后在客户端上解析它,但它非常难看 - 有更好的方法吗?
答案 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”。
对我来说不幸的是,我觉得整个答案都是一个题外话 从原始问题,并没有足够的功绩 一个问题本身就是一个问题。所以感谢大家帮助我 通过次要问题回答(与原始问题无关)。