Я использую модуль подпроцесса для запуска команды 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)
С помощью этого кода индикатор выполнения печатается только в конце процесса, но я хочу распечатать прогресс в реальном времени.





Из этот ответ вы можете отключить буферизацию при печати в python:
You can skip buffering for a whole python process using "python -u" (or
#!/usr/bin/env python -uetc) or by setting the environment variablePYTHONUNBUFFERED.You could also replace
sys.stdoutwith 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
Спасибо за помощь. Но, хотя -u, безусловно, полезен, я хочу отображать результат сценария bash через python. Например, я хочу иметь возможность использовать команду run внутри записной книжки jupyter и печатать результат, или ждать, пока будет записана определенная строка для выполнения действия, или просто распечатать результат команды bash. Если я просто использую -u и (например), os.system (cmd), я не смогу этого сделать.