我在使用Python执行shell cmd时尝试做两件事:
我查看了subprocess.check_output
,但它没有stdout参数,可以让我在输出时打印输出。
所以在阅读this question之后,我意识到我可能需要尝试不同的方法。
from subprocess import Popen, PIPE
process = Popen(task_cmd, stdout = PIPE)
stdout, stderr = process.communicate()
print(stdout, stderr)
这种方法的问题在于根据文档Popen.communicate():
从stdout和stderr读取数据,直到达到文件结尾。 等待进程终止
我似乎仍然无法将输出重定向到stdout AND到某种缓冲区,可以在命令完成时解析。
理想情况下,我喜欢以下内容:
# captures the process output and dumps it to stdout in realtime
stdout_capture = Something(prints_to_stdout = True)
process = Popen(task_cmd, stdout = stdout_capture)
# prints the entire output of the executed process
print(stdout_capture.complete_capture)
是否有推荐的方法来实现这一目标?
答案 0 :(得分:0)
使用赋予Popen stdout=PIPE
的方法是正确的,但是不能使用.communicate()
,因为它会在执行后返回值。相反,我建议您阅读.stdout
。
获取输出的唯一保证方法是一次从管道读取一个字符。这是我的方法:
def passthrough_and_capture_output(args):
import sys
import subprocess
process = subprocess.Popen(args, stdout=subprocess.PIPE, universal_newlines=True)
# universal_newlines means that the output of the process will be interpreted as text
capture = ""
s = process.stdout.read(1)
while len(s) > 0:
sys.stdout.write(s)
sys.stdout.flush()
capture += s
s = process.stdout.read(1)
return capture
请注意,一次读取一个字符会产生大量开销,因此,如果您稍稍落后一点,我建议您用不同数量的字符替换1
中的read(1)
批量输出。
答案 1 :(得分:-1)
from subprocess import check_output, CalledProcessError
def shell_command(args):
try:
res = check_output(args).decode()
except CalledProcessError as e:
res = e.output.decode()
for r in ['\r', '\n\n']:
res = res.replace(r, '')
return res.strip()