stderr очищается до начала stdout, при использовании файлового регистратора

Мой код python:

import sys print "i am a daemon" print "i will be run using nohup" sys.stderr.write("i am an error message inside nohup process\n") 

Когда я запускаю код как python a.py , он показывает,

 i am a daemon i will be run using nohup i am an error message inside nohup process 

Когда я запускаю код как nohup python a.py > a.log 2>&1 < /dev/null & , a.log показывает,

 i am an error message inside nohup process i am a daemon i will be run using nohup 

Почему журналы stderr очищаются / записываются перед журналами stdout при использовании nohup ?

2 Solutions collect form web for “stderr очищается до начала stdout, при использовании файлового регистратора”

Я не думаю, что это связано с nohup . Вы получаете такое же поведение, когда выполняете python a.py > a.log 2>&1 .

Python, скорее всего, использует C-файл stdio внизу. При этом stdout , когда в терминале, будет буферизироваться по строке и буферизируется, когда stdout является файлом. stderr всегда не загружается.

Перенаправление stdout в файл будет переключать буферизацию stdout с буферизированной строки на буферизацию и заставлять строку print быть застрявшей в буфере, которая очищается только тогда, когда ваша программа (поток) закрывается. Поток stderr делает его в файл быстрее, потому что он не загружен.

Вы можете использовать stdbuf для настройки стандартной буферизации, заставляя строки печатать в правильном порядке:

 stdbuf -o0 python a.py >a.log 2>&1 

Это нормальное поведение для выходных потоков на большинстве языков: они буферизованы , то есть write самом деле записывается в буфер в памяти, и этот буфер записывается в поток партиями. Stdout выравнивается по строке при записи на терминал (т.е. фактическая запись выполняется каждый раз при печати новой строки), но полностью буферизируется (данные записываются в память до тех пор, пока буфер памяти не будет заполнен) при записи в обычный файл или канал. Stderr не является буфером или буфером.

В Python вы можете выбрать тип буферизации при открытии файла, но не для стандартных потоков. Если вы хотите, чтобы все потоки были небуферизованными, вы можете установить PYTHONUNBUFFERED среды PYTHONUNBUFFERED чтобы заставить стандартные потоки быть небуферизованными. Кроме того, вы можете запустить программу под stdbuf или stdbuf .

Но если ваша программа не выводит вывод в соответствующем порядке при перенаправлении stdout, это дефект в программе, который вы должны исправить. В частности, если вы собираетесь выпустить сообщение об ошибке, относящееся к выходу, записанному на stdout, сначала нужно выполнить стрижку stdout:

 print some_data if errro_condition(): file.stdout.flush() sys.stderr.write('Bad stuff happened\n') 
  • Несогласованность перенаправления stderr между tcsh и другими оболочками
  • Перенаправление stdout и stderr все еще печатает на stdout
  • shell stderr to / dev / null
  • Скопируйте stdout и stderr в файл журнала и оставьте их на консоли в самом скрипте
  • Труба не поднимает stdout
  • отправка вывода в / dev / stderr vs.> & 2
  • Сообщение об ошибке скрипта в одной строке
  • Должен ли я выводить имя программы при возникновении предупреждения или ошибки?
  • Как перенаправить одно и то же сообщение на stdoud и stderr (без временного объекта)
  • Различные сообщения об ошибках при использовании разных строк в терминале
  • Когда использовать стандартный поток ошибок в приложении командной строки?
  • Linux и Unix - лучшая ОС в мире.