python - Python 子进程的实时输出

标签 python django python-3.x django-channels

我正在运行 Django Web 服务器,并尝试将子进程的输出实时打印到日志中。如果我推荐 readline 行并取消注释 yowzer 行,我会得到所需的记录输出流,但是一旦我尝试按原样运行此行,我就不会得到任何输出。我究竟做错了什么?我能找到的所有结果似乎都表明这可以按原样工作。

sp = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)

while sp.poll() is None:
    logging.critical(sp.stdout.readline())
    #logging.critical('yowzer')
    time.sleep(10)

谢谢!

[编辑 4 月 3 日] 事实证明,问题不在于该命令长时间运行,而在于我使用分号将“su user”命令与主命令连接起来。命令。删除 su 解决了问题。

最佳答案

在 Python 中调用子进程时,获取(或者更确切地说,未获取)实时输出是一个长期的烦恼。请参阅this question进行深入讨论,但简短的版本是,将关键字 arg bufsize=1 添加到 Popen 调用可能是您需要的 secret 武器。

另外,为什么你有time.sleep(10)?您确实意识到这意味着您必须在每行记录之间等待 10 秒,对吧?尝试重构您为读取输出而进行的调用。假设您使用的是 Python 3,请尝试以下操作:

from subprocess import PIPE, Popen

with Popen(command, shell=True, stdout=PIPE, bufsize=1) as sp:
    for line in sp.stdout:
        logging.critical(line)

我刚刚测试了上面的代码并可以确认它的工作原理。 Try it out yourself here 。链接的测试版本在日志的每一行之前打印时间戳。

如果仍然不起作用

如果您调用的子进程没有定期刷新其输出,那么您在 Python 脚本中无能为力。你提到了 Django ,对吧?您尝试记录的输出是通过标准 Python print() 调用生成的吗?如果是这样,您可以修改它们以更积极地刷新:

print(s, flush=True)

每个other language我使用过的也有一个等效的刷新命令,因此(假设您有权访问/可以修改子进程的源)您应该能够完成这项工作。

关于python - Python 子进程的实时输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49544927/

相关文章:

django - 我日志中的这些 CONNECT 消息是什么?

mysql - 我想导出没有 "b"的 csv 文件

python-3.x - 如何通过python代码创建和发送邮件而不用在odoo中的xml中创建邮件模板

python - 如何删除输出之间的多余空格?

python - mongodb 在聚合时从同一文档的数组中获取唯一值

python - 如何读取具有特定数据类型的文件内容,而不是Python中的字符串?

python - Django 测试错误

django - 部署的 Django 项目不加载静态文件

python 多处理不起作用?

python - 破解 Jinja2 以从 `utf-8` 而不是 `ascii` 编码?