作者:外包小王子 | 来源:互联网 | 2023-01-15 12:23
让我们考虑一下这个片段:
from subprocess import Popen, PIPE, CalledProcessError
def execute(cmd):
with Popen(cmd, shell=True, stdout=PIPE, bufsize=1, universal_newlines=True) as p:
for line in p.stdout:
print(line, end='')
if p.returncode != 0:
raise CalledProcessError(p.returncode, p.args)
base_cmd = [
"cmd", "/c", "d:\\virtual_envs\\py362_32\\Scripts\\activate",
"&&"
]
cmd1 = " ".join(base_cmd + ['python -c "import sys; print(sys.version)"'])
cmd2 = " ".join(base_cmd + ["python -m http.server"])
如果我运行execute(cmd1)
输出将打印没有任何问题.
但是,如果我运行execute(cmd2)
而不会打印任何内容,为什么会这样,我如何修复它,以便我可以实时看到http.server的输出.
另外,如何for line in p.stdout
在内部进行评估?是什么样的无限循环,直到达到stoout eof或什么?
这个主题在SO中已经解决了几次,但我还没有找到一个Windows解决方案.上面的片段实际上是来自这个答案的代码并尝试从virtualenv运行http.server(在win7上运行python3.6.2-32bits)
1> Oleh Rybalch..:
使用此代码,由于缓冲,您无法看到实时输出:
for line in p.stdout:
print(line, end='')
但如果你使用p.stdout.readline()
它应该工作:
while True:
line = p.stdout.readline()
if not line: break
print(line, end='')
有关详细信息,请参阅相应的python bug讨论
UPD:在这里你可以找到与 stackoverflow 上的各种解决方案几乎相同的问题.
2> fpbhb..:
如果要从正在运行的子进程中连续读取,则必须使该进程的输出无缓冲.您的子进程是一个Python程序,这可以通过传递-u
给解释器来完成:
python -u -m http.server
这就是它在Windows机器上的外观.