
У меня есть программа long_interactive_script.py
, в которой тысячи print
операторов. Я хочу передать программу по конвейеру tee
(или альтернативно), чтобы сохранить вывод.
Если я сделаю
long_interactive_script.py | tee logfile.txt
Python помещает свои операторы печати в буфер размером 4 КБ, в результате чего я получаю:
ничего, ничего, ничего, ничего, целая куча текста!, ничего, ничего, приглашение sudo посреди слова, ничего, ничего, целая куча текста!
В попытке избежать буфера я попробовал:
unbuffer long_interactive_script.py | tee logfile.txt
Но это приводит к тому, что мой скрипт перестает быть интерактивным. Поэтому, когда скрипт прерывается насудобыстро, он останавливается.
Примечание: Я не могу просто sudo
ДО запуска скрипта. Интерактивный скрипт требует только sudo
в некоторых запусках, и я не хочу спрашивать, sudo
когда это не нужно.
Более...
stdbuf -oL long_interactive_script.py | tee -a logfile.txt
работает в некоторой степени. Я получаю все желаемые данные, но также получаю эту ошибку:
ERROR: ld.so: object '/usr/lib64/coreutils/libstdbuf.so' from LD_PRELOAD cannot be preloaded: ignored.
решение1
Укажите буфер нулевого размера для стандартного выходного потока Python. Это можно сделать, вызвав Python с флагом -u
или с помощью следующего оператора.
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
решение2
Несмотря на обходные пути для буферизации, именно поэтому другие используютscript
, который фиксирует все символы, выводимые на терминал, не мешая интерактивным подсказкам.
Полученный typescript
файл немного уродливее, чем просто перенаправление на стандартный вывод, но (при условии, что ваше приложение предоставляло полезную информацию в этом режиме) будет достаточно просто обрезать символы возврата каретки.
Помимо возвратов каретки, есть еще символы редактирования, которые нужно отфильтровать. Смотрите, например: