我的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
?
答案1
我不认为这有什么关系nohup
。当您这样做时,您会得到相同的行为python a.py > a.log 2>&1
。
Python 很可能在底层使用 C 文件 stdio。这样,stdout
当在终端中时,将进行行缓冲,并在stdout
是文件时进行缓冲。stderr
始终是无缓冲的。
重定向stdout
到文件会将stdout
的缓冲从行缓冲切换为缓冲,并导致print
ed 字符串卡在缓冲区中,只有当程序(流)关闭时才会刷新。由于流stderr
是无缓冲的,因此它可以更快地传输到文件。
您可以使用stdbuf
调整标准缓冲,强制行以正确的顺序打印:
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')