gpt4 book ai didi

python - 从子进程中实时捕获标准输出

转载 作者:IT老高 更新时间:2023-10-28 21:35:15 27 4
gpt4 key购买 nike

我想在 Windows 中 subprocess.Popen() rsync.exe,并在 Python 中打印标准输出。

我的代码可以工作,但在文件传输完成之前它无法捕捉进度!我想实时打印每个文件的进度。

现在使用 Python 3.1,因为我听说它应该更好地处理 IO。

import subprocess, time, os, sys

cmd = "rsync.exe -vaz -P source/ dest/"
p, line = True, 'start'


p = subprocess.Popen(cmd,
shell=True,
bufsize=64,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)

for line in p.stdout:
print(">>> " + str(line.rstrip()))
p.stdout.flush()

最佳答案

subprocess 的一些经验法则。

  • 从不使用 shell=True。它不必要地调用一个额外的 shell 进程来调用您的程序。
  • 调用进程时,参数作为列表传递。 python 中的 sys.argv 是一个列表,C 中的 argv 也是如此。所以你将 list 传递给 Popen 调用子进程,而不是字符串。
  • 不阅读时不要将 stderr 重定向到 PIPE
  • 当你不写的时候不要重定向 stdin

例子:

import subprocess, time, os, sys
cmd = ["rsync.exe", "-vaz", "-P", "source/" ,"dest/"]

p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)

for line in iter(p.stdout.readline, b''):
print(">>> " + line.rstrip())

也就是说,当 rsync 检测到它连接到管道而不是终端时,它可能会缓冲其输出。这是默认行为 - 当连接到管道时,程序必须显式刷新标准输出以获得实时结果,否则标准 C 库将缓冲。

要对此进行测试,请尝试运行它:

cmd = [sys.executable, 'test_out.py']

并创建一个包含以下内容的 test_out.py 文件:

import sys
import time
print ("Hello")
sys.stdout.flush()
time.sleep(10)
print ("World")

执行该子进程应该给您“Hello”并等待 10 秒,然后再给“World”。如果上面的 python 代码而不是 rsync 发生这种情况,这意味着 rsync 本身正在缓冲输出,所以你不走运。

一种解决方案是直接连接到 pty,使用类似 pexpect 之类的东西。

关于python - 从子进程中实时捕获标准输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1606795/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com