我正在寻找一种 Python 解决方案,它允许我将命令的输出保存在文件中,而不会将其隐藏在控制台中。
仅供引用:我问的是 tee (作为 Unix 命令行实用程序)而不是 Python intertools 模块中的同名函数。
详情
- Python解决方案(不调用
tee
,Windows下不可用) - 我不需要为被调用的进程向标准输入提供任何输入
- 我无法控制被调用的程序。我所知道的是,它会向 stdout 和 stderr 输出一些内容并返回退出代码。
- 在调用外部程序(子进程)时工作
- 同时适用于
stderr
和stdout
- 能够区分 stdout 和 stderr 因为我可能只想向控制台显示其中一个,或者我可以尝试使用不同的颜色输出 stderr - 这意味着
stderr = subprocess.STDOUT
行不通。 - 实时输出(渐进式) - 进程可以运行很长时间,我无法等待它完成。
- Python 3 兼容代码(重要)
引用文献
以下是我目前找到的一些不完整的解决方案:
- http://devlishgenius.blogspot.com/2008/10/logging-in-real-time-in-python.html (mkfifo 仅适用于 Unix)
- http://blog.kagesenshi.org/2008/02/teeing-python-subprocesspopen-output.html (根本不起作用)
Diagram http://blog.i18n.ro/wp-content/uploads/2010/06/Drawing_tee_py.png
当前代码(第二次尝试)
#!/usr/bin/python
from __future__ import print_function
import sys, os, time, subprocess, io, threading
cmd = "python -E test_output.py"
from threading import Thread
class StreamThread ( Thread ):
def __init__(self, buffer):
Thread.__init__(self)
self.buffer = buffer
def run ( self ):
while 1:
line = self.buffer.readline()
print(line,end="")
sys.stdout.flush()
if line == '':
break
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdoutThread = StreamThread(io.TextIOWrapper(proc.stdout))
stderrThread = StreamThread(io.TextIOWrapper(proc.stderr))
stdoutThread.start()
stderrThread.start()
proc.communicate()
stdoutThread.join()
stderrThread.join()
print("--done--")
#### test_output.py ####
#!/usr/bin/python
from __future__ import print_function
import sys, os, time
for i in range(0, 10):
if i%2:
print("stderr %s" % i, file=sys.stderr)
else:
print("stdout %s" % i, file=sys.stdout)
time.sleep(0.1)
实际输出
stderr 1
stdout 0
stderr 3
stdout 2
stderr 5
stdout 4
stderr 7
stdout 6
stderr 9
stdout 8
--done--
预期的输出是对行进行排序。备注,修改 Popen 以仅使用一个 PIPE 是不允许的,因为在现实生活中我会想用 stderr 和 stdout 做不同的事情。
即使在第二种情况下,我也无法获得实时的输出,实际上所有结果都是在过程完成时收到的。默认情况下,Popen 不应该使用缓冲区 (bufsize=0)。
最佳答案
我看到这是一个相当老的帖子,但以防万一有人仍在寻找这样做的方法:
proc = subprocess.Popen(["ping", "localhost"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
with open("logfile.txt", "w") as log_file:
while proc.poll() is None:
line = proc.stderr.readline()
if line:
print "err: " + line.strip()
log_file.write(line)
line = proc.stdout.readline()
if line:
print "out: " + line.strip()
log_file.write(line)
关于python - 使用子进程时如何在 Python 中复制 tee 行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2996887/