我正在使用 subprocess 模块来运行 bash 命令。我想实时显示结果,包括没有添加新行但输出仍然被修改的情况。
我使用的是 python 3。我的代码使用子进程运行,但我对任何其他模块开放。我有一些代码可以为每添加一个新行返回一个生成器。
import subprocess
import shlex
def run(command):
process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
while True:
line = process.stdout.readline().rstrip()
if not line:
break
yield line.decode('utf-8')
cmd = 'ls -al'
for l in run(cmd):
print(l)
例如,问题来自 rsync -P file.txt file2.txt
形式的命令,它显示一个进度条。
例如,我们可以从在 bash 中创建一个大文件开始:
base64 /dev/urandom | head -c 1000000000 > file.txt
然后尝试用python显示rsync命令:
cmd = 'rsync -P file.txt file2.txt'
for l in run(cmd):
print(l)
通过这段代码,只在进程结束时打印进度条,但我想实时打印进度。
最佳答案
来自 this answer你可以在 python 中打印时禁用缓冲:
You can skip buffering for a whole python process using "python -u" (or
#!/usr/bin/env python -u
etc) or by setting the environment variablePYTHONUNBUFFERED
.You could also replace
sys.stdout
with some other stream like wrapper which does a flush after every call.Something like this (not really tested) might work...but there are probably problems that could pop up. For instance, I don't think it will work in IDLE, since sys.stdout is already replaced with some funny object there which doesn't like to be flushed. (This could be considered a bug in IDLE though.)
>>> class Unbuffered:
.. def __init__(self, stream):
.. self.stream = stream
.. def write(self, data):
.. self.stream.write(data)
.. self.stream.flush()
.. def __getattr__(self, attr):
.. return getattr(self.stream, attr)
..
>>> import sys
>>> sys.stdout=Unbuffered(sys.stdout)
>>> print 'Hello'
Hello
关于python-3.x - 实时打印在 Python 中使用子进程启动的 bash 命令的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53896978/