Python 为什么在连接到使用supervisord运行的进程时,stdout不刷新?

Python 为什么在连接到使用supervisord运行的进程时,stdout不刷新?,python,unix,terminal,supervisord,Python,Unix,Terminal,Supervisord,我正在使用Supervisor(用python编写的process controller)来启动和控制我的web服务器和相关服务。我发现有时需要进入pdb(或者真正的ipdb)以便在服务器运行时进行调试。我很难通过主管做到这一点 Supervisor允许使用名为supervisord的守护进程启动和控制进程,并通过名为supervisorctl的客户端提供访问。此客户端允许您附加到已使用“fg”命令启动的某个前台进程。像这样: supervisor> fg webserver 所有日志数

我正在使用Supervisor(用python编写的process controller)来启动和控制我的web服务器和相关服务。我发现有时需要进入pdb(或者真正的ipdb)以便在服务器运行时进行调试。我很难通过主管做到这一点

Supervisor允许使用名为supervisord的守护进程启动和控制进程,并通过名为supervisorctl的客户端提供访问。此客户端允许您附加到已使用“fg”命令启动的某个前台进程。像这样:

supervisor> fg webserver
所有日志数据都被发送到终端。但是我没有从pdb调试器中获得任何文本。它确实接受了我的输入,所以stdin似乎在工作

作为我调查的一部分,我能够确认无论是
打印
还是
原始输入
发送和文本输出;但是在
原始输入的情况下
标准输入确实在工作

我还能够确认这是可行的:

sys.stdout.write('message')
sys.flush()
我认为,当我发出
fg
命令时,就好像我在标准终端的前台运行了这个进程一样。。。但似乎Supervisortl正在做更多的事情。例如,常规打印不会刷新。有什么想法吗

使用supervisorctl中的
fg
命令连接前台终端时,如何使pdb、标准打印等正常工作?


(可能有用的参考:)

可能是您的Web服务器将其自身的标准输出重定向(内部)到日志文件(即忽略supervisord的标准输出重定向),从而阻止supervisord控制其标准输出的位置

要检查是否是这种情况,您可以
tail-f
日志,并查看您希望在终端中看到的输出是否在那里


如果是这种情况,请查看是否可以找到一种方法来配置Web服务器,使其不执行此操作,或者,如果所有其他操作都失败,请尝试使用两个终端。。。(一个用于输入,一个用于输出)

事实证明python默认缓冲其输出流。在某些情况下(例如本例),它会导致输出被扣留

有这样的成语:

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
将缓冲区强制为零

但我认为更好的选择是使用
-u
标志在无缓冲状态下启动基本python进程。在supervisord.conf文件中,它变成:

command=python -u script.py
参考:

还要注意的是,这会弄脏日志文件,特别是当您使用类似于带ANSI颜色的ipdb的东西时。但由于它是一个开发环境,所以这不太可能重要


如果这是一个问题-另一个解决方案是在supervisorctl中停止要调试的进程,然后在另一个终端中临时运行该进程以进行调试。如果需要,这将保持日志文件的干净。

My webserver不会将其输出发送到日志文件。它将它发送到stdout。另一件奇怪的事情是,当我终止进程时,一些(但不是全部)“卡住”的输出会在最后刷新到日志文件中。我开始觉得主管可能有点不对劲…不。。。我最后的评论不是真的。。。这不是主管的错。。。查看我发布的解决方案。这是:
fflush('stdout')应该可以。该死,我还没来得及给你贴答案,你就已经有了自己的答案。:-)注意:当python检测到
stdout
是一个终端(is
True
)时,就会使用行缓冲打开
stdout
(因此
buffering=1
而不是
0
)。哈哈!遗憾的是,当你周末工作时,你天生就不耐烦。谢谢你“几乎”的回答。。。还有
os.isatty()
上的附加信息。我希望这能解决我的脚本在使用supervisor时没有写入文件的问题?