내 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
stdout 로그를 사용할 때 stderr 로그가 플러시/기록되는 이유는 무엇입니까 nohup
?
답변1
나는 그것이 중요하지 않다고 생각합니다 nohup
. 이렇게 하면 동일한 동작이 발생합니다 python a.py > a.log 2>&1
.
Python은 내부적으로 C 파일 stdio를 사용할 가능성이 높습니다. 이렇게 하면 stdout
터미널에 있을 때 라인 버퍼링이 발생하고 stdout
파일일 때 버퍼링이 발생합니다. stderr
항상 버퍼링되지 않습니다.
stdout
파일로 리디렉션하면 stdout
버퍼링이 라인 버퍼링에서 버퍼링으로 전환되고 print
ed 문자열이 버퍼에 걸리고 프로그램(스트림)이 닫힐 때만 플러시됩니다. 스트림은 stderr
버퍼링되지 않으므로 파일로 더 빠르게 전송됩니다.
stdbuf
adjustStandardBuffering을 사용하여 라인을 올바른 순서로 강제로 인쇄 할 수 있습니다 .
stdbuf -o0 python a.py >a.log 2>&1
답변2
이는 대부분의 언어에서 출력 스트림의 일반적인 동작입니다.버퍼링됨즉, write
메모리의 버퍼가 실제로 기록되고, 버퍼가 일괄적으로 스트림에 기록됩니다. 터미널에 쓸 때 표준 출력은 라인 버퍼링되지만(즉, 개행 문자가 인쇄될 때마다 실제 쓰기가 발생함) 일반 파일이나 파이프에 쓸 때 표준 출력은 완전히 버퍼링됩니다(데이터는 메모리에 기록될 때까지) 메모리 버퍼가 가득 찼습니다.) Stderr는 버퍼링되지 않거나 라인 버퍼링됩니다.
Python에서는 파일을 열 때 버퍼링 유형을 선택할 수 있지만 표준 스트림은 선택할 수 없습니다. 모든 스트림을 버퍼링 해제하려면 다음을 설정할 수 있습니다.PYTHONUNBUFFERED
환경 변수는 표준 스트림이 버퍼링되지 않도록 강제합니다. 아니면 할 수 있습니다stdbuf
또는 아래에서 프로그램을 실행하십시오.unbuffer
.
그러나 표준 출력이 리디렉션될 때 프로그램이 올바른 순서로 출력을 내보내지 않으면 이는 수정해야 하는 프로그램의 결함입니다. 특히, stdout에 기록된 출력과 관련된 오류 메시지를 발행하려면 먼저 stdout을 플러시해야 합니다.
print some_data
if errro_condition():
file.stdout.flush()
sys.stderr.write('Bad stuff happened\n')