Наблюдаю за тем, как что-то записывается в файл в реальном времени с помощью tail

Наблюдаю за тем, как что-то записывается в файл в реальном времени с помощью tail

У меня есть программа на 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 работает успешно и немедленно.

С уважением

Связанный контент