У меня есть программа на Python, которая медленно генерирует какой-то вывод.
Я хочу запечатлеть это в файле, но также подумал, что смогу посмотреть это вживую с помощью Tail.
Итак, в одном терминале я делаю:
python myprog.py > output.txt
и в другом терминале:
tail -f output.txt
Но, похоже, tail ничего мне не показывает, пока выполняется программа Python.
Если я нажму ctrl-c, чтобы завершить скрипт python, хвост внезапно output.txt
начнет заполняться. Но не во время работы python.
Что я делаю не так?
решение1
Вам также может потребоваться явно очистить буфер, чтобы он был передан по конвейеру при генерации. Это связано с тем, что вывод обычно печатается только тогда, когда буфер конвейера заполняется (что, как я полагаю, в килобайтах) и когда заканчивается сообщение stdin. Вероятно, это сделано для экономии на чтении/записи. Вы можете сделать это после каждой печати или, если вы зацикливаете, после последней печати в цикле.
import sys
...
print('Some message')
sys.stdout.flush()
решение2
Запустите python с флагом unbuffered:
python -u myprog.py > output.txt
После этого вывод будет осуществляться в режиме реального времени.
решение3
Вместо того, чтобы пытаться следить за живым файлом, используйте tee
вместо этого. Он был создан, чтобы делать именно то, что вы пытаетесь сделать.
tee(1) - страница руководства Linux
Имя tee - чтение из стандартного ввода и запись в стандартный вывод и файлы
Синопсис
tee [OPTION]... [FILE]...
Описание
Копировать стандартный ввод в каждый ФАЙЛ, а также в стандартный вывод.
-a, --append append to the given FILEs, do not overwrite -i, --ignore-interrupts ignore interrupt signals --help display this help and exit --version output version information and exit
Если ФАЙЛ равен -, скопировать еще раз в стандартный вывод.
Итак, в вашем случае вы бы запустили:
python myprog.py | tee output.txt
EDIT: Как указали другие, этот ответ столкнется с той же проблемой, которая изначально была у OP, если только не sys.stdout.flush()
используется в программе python, как описано в принятом ответе Дэйви. Тестирование, которое я провел перед публикацией этого ответа, не совсем точно отразило вариант использования OP.
tee
его все еще можно использовать как альтернативный (хотя и не самый оптимальный) метод отображения вывода с одновременной записью в файл, но ответ Дэйви, несомненно, правильный и лучший.
решение4
Когда я использую tail, он почти всегда отслеживает файл журнала, например, сообщения (электронной почты).
Это может показаться немного необычным, но вместо использования print
/ print()
/ write()
в коде Python, почему бы не использовать модуль ведения журнала? (из PSL) Примечание: форматировщик журнала можно настроить так, чтобы он НЕ выводил все эти временные и идентификационные коды, связанные с традиционным журналом.
Вывод можно настроить на отправку в файл (данных), и поскольку нет задержки буферизации или перенаправления, tail работает успешно и немедленно.
С уважением