在 Upstart 作业中捕获 Python 的 stdout

3

当我将一个Python2.6脚本作为upstart任务运行时,我很难将标准输出保存到文件中。

这是我的当前测试脚本:

#!/usr/bin/python
from time import sleep
import sys

while 1:
    print "Hello from stdout"
    print >> sys.stderr, "Hello from stderr"
    sleep(1)

如果我执行$ myscript >> /var/log/myscript,那么这将正常工作。我可以看到两者。
然而,如果我使用以下的upstart脚本,它就不起作用了。
  1. /etc/init/myscript.conf:

    exec /path/to/myscript >> /var/log/myscript 2>&1
    

    I see this:

    Hello from stderr
    Hello from stderr
    Hello from stderr
    Hello from stderr
    Hello from stderr
    Hello from stderr
    
如果我使用不同的文件来处理stderr和stdout,它们都会被创建,但是stdout始终为空。我做错了什么?
1个回答

3

缓冲和刷新可能是我们的猜测。

标准错误(stderr)通常是无缓冲流,而标准输出(stdout)是有缓冲流的。当您将其发送到文件时,它将以4k字节(通常)为块进行缓冲。

如果您进行以下更改:

while 1:
    print "hello from stdout"
    sys.stdout.flush()
    print >> sys.stderr, "Hello from stderr"
    sleep(1)

你应该在你的文件中看到输出。

我认为这可能是一个缓冲问题。我曾经假设当Python接收到SIGTERM时,它会自己刷新stdout。我猜解决这个问题的一个潜在方法是捕获SIGTERM并在那一点上刷新缓冲区。 - rod
是的,使用 flush() 处理 sigterm 将会得到你想要的结果。如果未处理 TERM,则会终止程序,尽管让默认处理程序刷新所有 IO 是一个有趣的想法... - koblas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接