Subproces.popen - 从站写入失败:管道损坏;中止
Subproces.popen - slave write failed: Broken pipe; aborting
TLDR:坚持这个 https://code.google.com/archive/p/byte-unixbench/issues/1
尝试使用 subprocess.popen()
运行 UnixBench,同时捕获输出并实时打印出来。
这是我想出的子程序:
def run_and_print(command, cwd=None, catch_stderr = False):
if catch_stderr:
err_pipe = subprocess.PIPE
else:
err_pipe = subprocess.STDOUT
p = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=1, cwd=cwd, stderr=err_pipe)
r = ''
while True:
if catch_stderr:
out = p.stderr.read(1)
else:
out = p.stdout.read(1)
if out == "" and p.poll() != None:
break
sys.stdout.write(out)
sys.stdout.flush()
r += out
return r
除了 UnixBench 之外,它在所有用途上都工作得很好。 Unixbench 在一段时间后就死了:
unixbench = run_and_print(['./Run'])
...
1 x Pipe Throughput 1 2 3 4 5 6 7 8 9 10
1 x Pipe-based Context Switching 1 2 3 4
Run: "Pipe-based Context Switching": slave write failed: Broken pipe; aborting
Google 没有多大帮助。我得到的唯一有意义的结果是 https://code.google.com/archive/p/byte-unixbench/issues/1 并且创建 java 应用程序的建议解决方案对我不起作用,因为我需要 运行 具有尽可能少的依赖项的脚本。
如果有任何解决方案或解决方法,我将不胜感激。我正在测试的系统是 Ubuntu 14.04.4 x64
该错误与 'yes' reporting error with subprocess communicate() 有关,后者提供修复:使用 preexec_fn
(或使用 Python 3)在子进程中重新启用 SIGPIPE
信号。
不相关:如果 catch_stderr
为真且 p.stderr
和 p.stdout
不完全同步,您的代码可能会死锁。
否则 catch_stderr
无效(忽略缓冲):您的代码无论如何都会捕获 stderr。你可以简化它:
#!/usr/bin/env python
from shutil import copyfileobj
from subprocess import Popen, PIPE, STDOUT
def run_and_print(command, cwd=None):
p = Popen(command, stdout=PIPE, stderr=STDOUT, bufsize=-1, cwd=cwd,
preexec_fn=restore_signals)
with p.stdout:
tee = Tee()
copyfileobj(p.stdout, tee)
return p.wait(), tee.getvalue()
其中 Tee()
是一个类似文件的对象,它写入两个地方:stdout 和 StringIO()
:
import sys
from io import BytesIO
class Tee:
def __init__(self):
self.file = BytesIO()
def write(self, data):
getattr(sys.stdout, 'buffer', sys.stdout).write(data)
self.file.write(data)
def getvalue(self):
return self.file.getvalue()
其中 restore_signals()
is defined here.
如果你想在命令打印出来后立即在屏幕上看到输出;您可以内联 Tee
、copyfileobj()
and use os.read()
,以避免在将其写入 stdout
:
之前读取完整的 length
chunks = []
with p.stdout:
for chunk in iter(lambda: os.read(p.stdout.fileno(), 1 << 13), b''):
getattr(sys.stdout, 'buffer', sys.stdout).write(chunk)
sys.stdout.flush()
chunks.append(chunk)
return p.wait(), b''.join(chunks)
要禁用子进程中的内部块缓冲,您可以尝试 run it using stdbuf
or pass pseudo-tty instead of the pipe。
TLDR:坚持这个 https://code.google.com/archive/p/byte-unixbench/issues/1
尝试使用 subprocess.popen()
运行 UnixBench,同时捕获输出并实时打印出来。
这是我想出的子程序:
def run_and_print(command, cwd=None, catch_stderr = False):
if catch_stderr:
err_pipe = subprocess.PIPE
else:
err_pipe = subprocess.STDOUT
p = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=1, cwd=cwd, stderr=err_pipe)
r = ''
while True:
if catch_stderr:
out = p.stderr.read(1)
else:
out = p.stdout.read(1)
if out == "" and p.poll() != None:
break
sys.stdout.write(out)
sys.stdout.flush()
r += out
return r
除了 UnixBench 之外,它在所有用途上都工作得很好。 Unixbench 在一段时间后就死了:
unixbench = run_and_print(['./Run'])
...
1 x Pipe Throughput 1 2 3 4 5 6 7 8 9 10
1 x Pipe-based Context Switching 1 2 3 4
Run: "Pipe-based Context Switching": slave write failed: Broken pipe; aborting
Google 没有多大帮助。我得到的唯一有意义的结果是 https://code.google.com/archive/p/byte-unixbench/issues/1 并且创建 java 应用程序的建议解决方案对我不起作用,因为我需要 运行 具有尽可能少的依赖项的脚本。
如果有任何解决方案或解决方法,我将不胜感激。我正在测试的系统是 Ubuntu 14.04.4 x64
该错误与 'yes' reporting error with subprocess communicate() 有关,后者提供修复:使用 preexec_fn
(或使用 Python 3)在子进程中重新启用 SIGPIPE
信号。
不相关:如果 catch_stderr
为真且 p.stderr
和 p.stdout
不完全同步,您的代码可能会死锁。
否则 catch_stderr
无效(忽略缓冲):您的代码无论如何都会捕获 stderr。你可以简化它:
#!/usr/bin/env python
from shutil import copyfileobj
from subprocess import Popen, PIPE, STDOUT
def run_and_print(command, cwd=None):
p = Popen(command, stdout=PIPE, stderr=STDOUT, bufsize=-1, cwd=cwd,
preexec_fn=restore_signals)
with p.stdout:
tee = Tee()
copyfileobj(p.stdout, tee)
return p.wait(), tee.getvalue()
其中 Tee()
是一个类似文件的对象,它写入两个地方:stdout 和 StringIO()
:
import sys
from io import BytesIO
class Tee:
def __init__(self):
self.file = BytesIO()
def write(self, data):
getattr(sys.stdout, 'buffer', sys.stdout).write(data)
self.file.write(data)
def getvalue(self):
return self.file.getvalue()
其中 restore_signals()
is defined here.
如果你想在命令打印出来后立即在屏幕上看到输出;您可以内联 Tee
、copyfileobj()
and use os.read()
,以避免在将其写入 stdout
:
length
chunks = []
with p.stdout:
for chunk in iter(lambda: os.read(p.stdout.fileno(), 1 << 13), b''):
getattr(sys.stdout, 'buffer', sys.stdout).write(chunk)
sys.stdout.flush()
chunks.append(chunk)
return p.wait(), b''.join(chunks)
要禁用子进程中的内部块缓冲,您可以尝试 run it using stdbuf
or pass pseudo-tty instead of the pipe。