我想在Windows中subprocess.Popen()
rsync.exe,并用Python打印stdout。
我的代码可以工作,但在文件传输完成之前,它不会捕获进度!我想实时打印每个文件的进度。
现在使用Python3.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()
我知道这是个老话题,但现在有了解决办法。使用选项--outbuf=L调用rsync。示例:
关于
subprocess
的一些经验法则。shell=True
。它不必要地调用额外的shell进程来调用您的程序。argv
也是这样。因此,您将列表传递给Popen
以调用子进程,而不是字符串。stderr
重定向到PIPE
。stdin
。示例:
也就是说,当rsync检测到它连接到管道而不是终端时,它很可能会缓冲它的输出。这是默认行为-当连接到管道时,程序必须显式刷新stdout以获得实时结果,否则标准C库将缓冲。
要进行测试,请尝试运行以下命令:
并创建一个包含以下内容的
test_out.py
文件:执行该子流程时,应该给出“Hello”,并在给出“World”之前等待10秒。如果这发生在上面的python代码上,而不是
rsync
,那就意味着rsync
本身正在缓冲输出,所以您运气不好。一种解决方案是使用类似
pexpect
的方法直接连接到pty
。在Linux上,我也遇到了同样的问题,即去掉缓冲区。我最后使用了“stdbuf-o0”(或者,unbuffer from expect)来消除管道缓冲。
然后我可以在stdout上使用select.select。
另见https://unix.stackexchange.com/questions/25372/
相关问题 更多 >
编程相关推荐