为什么子进程不以 Python 2.7 终止?
Why subprocess does not terminate with Python 2.7 only?
我有一个代码生成一个进程 subprocess.Popen
:
from subprocess import check_call, CalledProcessError, Popen, PIPE
cmd="while true; do echo 123; done | grep -m1 123"
proc = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
当我用 Python 3.9.2 运行 时,它会按预期立即终止。但是,当我 运行 它与 Python 2.7 挂起时。似乎 Python 2.7 等待 shell 无限循环终止,但它永远不会终止。我也可以让这段代码在 Python 2.7 下终止吗?
找到相关问题 Python subprocess.Popen blocks with shell and pipe for Python 2.7. The problem is that in Python 2.7 SIGPIPE
signal is ignored by default and therefore while true
loop ignores the fact that grep
terminates on first match. There is unresolved Python issue for this https://bugs.python.org/issue1652。在 Python 3 上,subprocess.Popen
有一个额外的参数 restore_signals=True
,因此上面的代码按原样工作。对于 Python 2.7,可以这样修改以恢复 SIGPIPE
信号:
from subprocess import check_call, CalledProcessError, Popen, PIPE
import signal
def restore_signals():
signals = ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ')
for sig in signals:
if hasattr(signal, sig):
signal.signal(getattr(signal, sig), signal.SIG_DFL)
cmd="while true; do echo 123; done | grep -m1 123"
proc = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, preexec_fn=restore_signals)
out, err = proc.communicate()
我有一个代码生成一个进程 subprocess.Popen
:
from subprocess import check_call, CalledProcessError, Popen, PIPE
cmd="while true; do echo 123; done | grep -m1 123"
proc = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
当我用 Python 3.9.2 运行 时,它会按预期立即终止。但是,当我 运行 它与 Python 2.7 挂起时。似乎 Python 2.7 等待 shell 无限循环终止,但它永远不会终止。我也可以让这段代码在 Python 2.7 下终止吗?
找到相关问题 Python subprocess.Popen blocks with shell and pipe for Python 2.7. The problem is that in Python 2.7 SIGPIPE
signal is ignored by default and therefore while true
loop ignores the fact that grep
terminates on first match. There is unresolved Python issue for this https://bugs.python.org/issue1652。在 Python 3 上,subprocess.Popen
有一个额外的参数 restore_signals=True
,因此上面的代码按原样工作。对于 Python 2.7,可以这样修改以恢复 SIGPIPE
信号:
from subprocess import check_call, CalledProcessError, Popen, PIPE
import signal
def restore_signals():
signals = ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ')
for sig in signals:
if hasattr(signal, sig):
signal.signal(getattr(signal, sig), signal.SIG_DFL)
cmd="while true; do echo 123; done | grep -m1 123"
proc = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, preexec_fn=restore_signals)
out, err = proc.communicate()