Popen.communicate()抛出OSError:"[Errno 10]没有子进程"

Laj*_*agy 9 python linux

我正在尝试使用子进程模块启动子进程并使用Python从Linux获取其输出:

#!/usr/bin/python2.4
import subprocess

p = subprocess.Popen(['ls', '-l', '/etc'],
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE)
out, err = p.communicate()
Run Code Online (Sandbox Code Playgroud)

但是,我经历了一些诡异:有时,p.communicate()会抛出

OSError: [Errno 10] No child processes
Run Code Online (Sandbox Code Playgroud)

什么可以导致这个例外?这里是否有任何非决定论或竞争条件会导致邋??

Vuk*_*man 6

您是否在脚本中拦截SIGCHLD?如果你是那么Popen将无法按预期运行,因为它依赖于它自己的信号处理程序.

您可以通过注释掉Popen调用然后运行来检查SIGCHLD处理程序:

strace python <your_script.py> | grep SIGCHLD
Run Code Online (Sandbox Code Playgroud)

如果你看到类似的东西:

rt_sigaction(SIGCHLD, ...)
Run Code Online (Sandbox Code Playgroud)

那么,你有麻烦了.您需要在调用Popen之前禁用处理程序,然后在完成通信后重置它(这可能会引入竞争条件,所以要小心).

signal.signal(SIGCHLD, handler)
...
signal.signal(SIGCHLD, signal.SIG_DFL)
'''
now you can go wild with Popen. 
WARNING!!! during this time no signals will be delivered to handler
'''
...
signal.signal(SIGCHLD, handler)
Run Code Online (Sandbox Code Playgroud)

报告了一个python错误,据我所知尚未解决:

http://bugs.python.org/issue9127

希望有所帮助.


Dav*_*yan 3

您可能会遇到这里提到的错误:http://bugs.python.org/issue1731717

  • 截至 2010 年 9 月 29 日,该错误仍标记为“开放/需要补丁”并影响版本 3.2、3.1、2.7、2.6。 (2认同)