我正在尝试将stdout重定向到屏幕,同时保存到变量并在AttributeError: __exit__
行遇到错误with proc.stdout:
,是否有人可以告诉我如何完成此操作?
...............
proc = subprocess.Popen(cmd.split(' '), stderr=subprocess.PIPE)
try:
proc.wait(timeout=time_out)
except TimeoutExpired as e:
print e
proc.kill()
with proc.stdout:
for line in proc.stdout:
print line
错误: -
with proc.stdout:
AttributeError: __exit__
更新 -
proc = subprocess.Popen(cmd.split(' '),stdout=subprocess.PIPE )
print "Executing %s"%cmd
try:
proc.wait(timeout=time_out)//HUNG here until timeout kicks-in
except TimeoutExpired as e:
print e
proc.kill()
with proc.stdout as stdout:
for line in stdout:
print line,
答案 0 :(得分:0)
创建Popen对象时,设置了stderr。当你打开stdout时,子进程无法打开它,因为你已经设置了stderr。您可以通过将stdout=subprocess.PIPE
添加到Popen对象args,或者通过with proc.stderr
而不是with proc.stderr
来解决此问题。另外,你想稍微改变你的声明,就像这样。
with proc.stdout as stdout:
for line in stdout:
sys.stdout.write(line)
答案 1 :(得分:0)
一旦你stdout
成为PIPE
,你就可以创建一个循环来读取管道并将其写入任意数量的地方。处理stderr
会使情况变得有点棘手,因为您还需要背景阅读器。因此,创建一个线程和一个写入多个文件的实用程序,您就完成了。
import sys
import threading
from StringIO import StringIO
import subprocess as subp
import shlex
def _file_copy_many(fp, *write_to):
"""Copy from one file object to one or more file objects"""
while True:
buf = fp.read(65536)
if not buf:
return
for fp in write_to:
fp.write(buf)
# for test
cmd = "ls -l"
# will hold stdout and stderr
outbuf = StringIO()
errbuf = StringIO()
# run the command and close its stdin
proc = subp.Popen(shlex.split(cmd), stdin=subp.PIPE, stdout=subp.PIPE,
stderr=subp.PIPE)
proc.stdin.close()
# background thread to write stderr to buffer
stderr_thread = threading.Thread(target=_file_copy_many,
args=(proc.stderr, errbuf))
stderr_thread.start()
# write stdout to screen and buffer then wait for program completion
_file_copy_many(proc.stdout, sys.stdout, outbuf)
return_code = proc.wait()
# wait for err thread
stderr_thread.join()
# use buffers
print outbuf.tell(), errbuf.tell()
outbuf.seek(0)
errbuf.seek(0)
这类似于subprocess.Popen.communicate
所做但写入更多目的地。