Leh*_*ych 6 python bash subprocess dash-shell
为什么
import subprocess
p = subprocess.Popen(["/bin/bash", "-c", "timeout -s KILL 1 sleep 5 2>/dev/null"])
p.wait()
print(p.returncode)
Run Code Online (Sandbox Code Playgroud)
回报
[stderr:] /bin/bash: line 1: 963663 Killed timeout -s KILL 1 sleep 5 2> /dev/null
[stdout:] 137
Run Code Online (Sandbox Code Playgroud)
什么时候
import subprocess
p = subprocess.Popen(["/bin/bash", "-c", "timeout -s KILL 1 sleep 5"])
p.wait()
print(p.returncode)
Run Code Online (Sandbox Code Playgroud)
回报
[stdout:] -9
Run Code Online (Sandbox Code Playgroud)
如果你将bash改为破折号,那么在这两种情况下你都会得到137.我知道-9是KILL代码而137是128 + 9.但类似的代码获得不同的返回码似乎很奇怪.
发生在Python 2.7.12和python 3.4.3上
看起来在使用时Popen.wait()不会调用Popen._handle_exitstatus https://github.com/python/cpython/blob/3.4/Lib/subprocess.py#L1468,/bin/bash但我无法弄清楚原因.
这是因为在有或没有重定向/管道或任何其他 bash 功能的情况下如何bash执行:timeout
带重定向
python开始bashbash启动timeout,监视进程并进行管道处理。timeout将自身转移到新的进程组并启动sleeptimeout发送SIGKILL到其进程组bash从等待返回timeout,看到SIGKILL并将上面粘贴的消息打印到stderr。然后它将自己的退出状态设置为 128+9(由 模拟的行为timeout)。不带重定向
python开始bash。bash认为它与自己无关,并呼吁execve()有效地用 来取代它自己timeout。timeout如上所述,整个进程组会随着 一起死亡SIGKILL。pythonget 的退出状态9并进行一些修改以将其变成-9( SIGKILL)换句话说,没有重定向/管道/等。bash从调用链中退出。您的第二个示例看起来subprocess.Popen()正在执行bash,但实际上并没有。bash它的行为何时不再存在timeout,这就是为什么您没有收到任何消息和完整的退出状态。
如果您想要一致的行为,请使用timeout --foreground; 在这两种情况下,您都会得到 124 的退出状态。
我不知道破折号;但假设它没有做任何execve()欺骗来有效地用它正在执行的唯一程序替换自己。因此,您总是会在破折号中看到 128+9 的损坏退出状态。
更新:显示相同的行为,但即使对于简单的重定向(例如等)zsh它也会退出,为您提供 -9 的退出状态。也会给你状态 137 。timeout -s KILL 1 sleep 5 >/tmp/footimeout -s KILL 1 sleep 5 && echo $?zsh
| 归档时间: |
|
| 查看次数: |
310 次 |
| 最近记录: |