Получить вывод PV с использованием Python

Есть ли способ использовать программу PV из Python, чтобы получить прогресс операции?

Пока у меня есть следующее:

    p0 = sp.Popen(["pv", "-f", args.filepath],
                  bufsize=0,
                  stdout=sp.PIPE,
                  stderr=sp.PIPE)
    p1 = sp.Popen(["awk", "{print $1, $2, $1, $3, $4 }",  "{}".format(args.filepath)],
                   stdout=sp.PIPE,
                   stdin=p0.stdout)

Но у меня возникают проблемы с получением постоянного вывода p0, Я старался:

    for line in p0.stderr:
        print("line:", line)

Но это ожидает завершения процесса, а затем печатает только последний отчет о проделанной работе. pv, Кто-нибудь знает, как я могу заставить его печатать постоянно обновляемый статус?

2 ответа

Решение

Оказывается pv выводит каждую строку с возвратом каретки в конце (\r). Чтобы иметь возможность непрерывно читать с выхода, Popen должен быть инициализирован с universal_lines=True, как это:

    p0 = sp.Popen(['pv', '-f', args.filepath],
                    stdout=sp.PIPE,
                    stderr=sp.PIPE,
                    universal_newlines=True)

Это приводит к постоянному выводу отчетов о проделанной работе:

line: 7.12MB 0:00:01 [ 7.1MB/s] [=>                                  ]  8% ETA 0:00:11

line: 14.6MB 0:00:02 [7.42MB/s] [====>                               ] 16% ETA 0:00:10

line: 22.1MB 0:00:03 [7.55MB/s] [=======>                            ] 24% ETA 0:00:09

line: 29.5MB 0:00:04 [7.36MB/s] [==========>                         ] 33% ETA 0:00:08

Вот ссылка на похожий вопрос:

Вывод в реальном времени subprocess.popen(), а не построчно

Попробуйте прочитать из p0.stderr

pv оставляет stdout нетронутым, пишет только в stderr

Попробуйте что-то вроде этого.

p = subprocess.Popen(command, stdout=subprocess.PIPE)

for line in iter(p.stdout.readline, ''):
    print("line", line)
Другие вопросы по тегам