Записать исходный файл Python в файл немедленно

При попытке записать stdout из сценария Python в текстовый файл ( python script.py > log ) текстовый файл создается при запуске команды, но фактический контент не записывается до завершения сценария Python. Например:

script.py:

 import time for i in range(10): print('bla') time.sleep(5) 

печатает в stdout каждые 5 секунд, когда python script.py с python script.py , но когда я вызываю python script.py > log , размер файла журнала остается нулевым до завершения скрипта. Можно ли напрямую записывать в файл журнала, чтобы вы могли следить за ходом выполнения скрипта (например, используя tail )?

  • Как написать скрипт, который может принимать входные данные из stdout
  • Как ограничить количество строк выходом команды в bash?
  • Подавлять сообщения о запуске на stdout?
  • Как обмануть команду в мысли, что ее выход идет на терминал
  • stdout, stderr и протоколирование с помощью команды script
  • Выполнять команду в удаленном активном терминале
  • Вывод скрипта python, выполняющегося как единица, не соответствует порядку, в то время как оболочки не отображаются
  • Как добавить новые строки при использовании эха
  • 3 Solutions collect form web for “Записать исходный файл Python в файл немедленно”

    Это происходит потому, что, как правило, когда процесс STDOUT перенаправляется на что-то другое, отличное от терминала, то вывод буферизуется в буфер определенного размера ОС (возможно, 4k или 8k во многих случаях). И наоборот, при выводе на терминал STDOUT будет буферизироваться по строке или вообще не буферизоваться, поэтому вы увидите вывод после каждого \n или для каждого символа.

    Обычно вы можете изменить буферизацию STDOUT с stdbuf утилиты stdbuf :

     stdbuf -oL python script.py > log 

    Теперь, если вы tail -F log , вы должны увидеть каждый вывод строки сразу же после его создания.


    Альтернативно явная промывка выходного потока после каждой печати должна достигать того же. Похоже, sys.stdout.flush() должен достичь этого в Python. Если вы используете Python 3.3 или новее, функция print также имеет ключевое слово flush которое делает это: print('hello', flush=True) .

    Это должно сделать работу:

     import time, sys for i in range(10): print('bla') sys.stdout.flush() time.sleep(5) 

    Поскольку Python будет буферизовать stdout по умолчанию, здесь я использовал sys.stdout.flush() чтобы очистить буфер.

    Другим решением было бы использовать -u (небуферизованный) переключатель python . Итак, следующее:

     python -u script.py >> log 

    Вы должны передать flush=True для функции print :

     import time for i in range(10): print('bla', flush=True) time.sleep(5) 

    Согласно документации, по умолчанию print не обеспечивает ничего о промывке:

    Буферизация вывода обычно определяется файлом, но если аргумент ключевого слова flush равен true, поток принудительно очищается.

    И документация для styss sys говорит:

    Когда интерактивные стандартные потоки буферизируются по строке. В противном случае они блокируются буфером, как обычные текстовые файлы. Вы можете переопределить это значение с помощью опции -u командной строки.


    Если вы застряли в древней версии python, вам нужно вызвать метод sys.stdout потока sys.stdout :

     import sys import time for i in range(10): print('bla') sys.stdout.flush() time.sleep(5) 
    Linux и Unix - лучшая ОС в мире.