我可以通过 ssh 获取在子 shell 中执行的命令的退出代码吗?
我正在尝试使用 Paramiko 编写部署脚本,但在运行命令的退出代码时遇到问题。我使用的代码类似于 这个答案,但有点复杂。基本上,从我们的开发盒中,我们必须经过一个跳转服务器,然后从那里到达一系列生产机器。一旦到达那里,我们必须切换到系统用户(sudo su - systemuser),然后我们可以运行命令。
问题是,据我了解,我有 3 个子 shell - ssh 会话、嵌套的 ssh 命令和 su 子 shell。我无法让 Paramiko 给我返回内部子 shell 中命令的退出代码 - 我猜它最终返回的退出代码将是 ssh 命令的退出代码。我怀疑这个问题实际上并不是 Paramiko 特有的 - SSH 协议是否支持这种用法?
我目前总是执行:
(my command); echo "Process terminated with exit code $?"
然后在客户端上解析它,但它非常丑陋 - 有更好的方法吗?
I'm trying to use Paramiko to write a deployment script, and I'm having trouble with exit codes from the commands I run. I'm using code similar to that in this answer, but it's a little more complicated. Basically, from our dev boxes we have to go through a jump server, and from there to a series of production machines. Once there we have to switch to a system user (sudo su - systemuser) and then we can run commands.
The problem is that as I understand it I have 3 subshells - the ssh session, the nested ssh command and then the su subshell. I can't get Paramiko to give me back the exit code of the commands in the inner subshell - I guess the exit code it will eventually return will be that of the ssh command. I suspect this problem is not actually specific to Paramiko - does the SSH protocol even support this kind of usage?
I'm currently always executing:
(my command); echo "Process terminated with exit code $?"
and then parsing this out on the client, but it's pretty ugly - is there a nicer way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,也不是。
退出状态总是会返回,但它可能不是来自您想象的地方。一旦调用
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
属性。Yes, and no.
The exit status is always returned, but it may not be from where you think. Once you call
invoke_shell()
, your remote process is a shell, probably bash. Theexit_status
you receive will be the one from that shell, not any of the processes it ran. Paramiko (nor any ssh implementation) can ever return the exit status of your commands, because the exit statuses are never seen outside of that remote shell. It's up to you to determine what your exit status should be, and exit the shell withexit $EXIT_STATUS
(oftenexit $?
is enough)If you can break up your commands, or wrap them in a script, then use the
exec_command()
method, you will have access to the correct exit status directly.Alternatively, you can use shell command
exec
in the remote shell, and the shell's process will be replaced by the command called by exec, and its exit status will be returned.All three of these methods will set the
channel.exit_status
attribute as expected.我遇到一个问题,“ssh”的手册页说它返回其运行的进程的退出代码,但我似乎无法让它返回非零错误代码。来自 ssh 手册页:
这似乎不是真的。
但我会尝试这样的事情,看看你的系统上会发生什么。
当我在本地运行类似的命令时,bash 返回退出代码。
然而,在 ssh 出现命令之前,双引号将被删除。
因此,让我们尝试更多引用。
宾果游戏。 “exit 3”变成了“exit”,后面跟着一个被忽略的词
在 bash 命令行上。所以 bash 正在运行命令“exit”。
对我来说不幸的是,我认为整个答案都是题外话
来自最初的问题并且没有包含足够的优点
这本身就是一个问题。所以感谢大家帮助我
通过次要问题回答(与原始问题无关)。
I'm having a problem where the man page for 'ssh' says that it returns the exit code of the process it runs, but I can't seem to get it to return a non-zero error code. From the ssh man page:
That doesn't seem to be true.
But I would try something like this and see what happens on your system.
When I run a similar command locally, bash returns an exit code.
The double quotes will be removed before ssh seems the commands however.
So let's try more quotes.
Bingo. The "exit 3" was turning into "exit" followed by an ignored word
on the bash command line. So bash was running the command "exit".
Unfortunately for me, I think this whole answer is a digression
from the original questions and doesn't contain enough merit as
a question in its own right. So thanks everyone for helping me
answer by secondary question (not related to the original question).