使用Popen时如何确保stdout写入文件

时间:2014-08-14 16:41:59

标签: python subprocess stdout popen

我有一个听众说“等待消息......”,然后永远等待来自各种程序的消息传递给响应者。当我从命令行运行它时,所有这一切都正常,但现在我想自动化它,所以我不必单独启动所有程序。

我开始只是试图让我的监听器启动,但是当我尝试将stdout路由到文件时,它不打印出“等待消息...”消息,或者根本没有打印出来。

from subprocess import Popen, PIPE

with open('listenerOutput', 'w') as outfile:
    Popen(["python", "listener.py"], stdout = outfile)

到目前为止,我所阅读的所有问题似乎都比这更复杂,但我似乎无法使这部分工作。据推测,listener.py中的任何print语句都会显示在outfile中,对吗?但我得到的只是一个空的'listenerOutput'文件。是否有一些额外的步骤使它写入文件,或者我是否采取了错误的方式?

2 个答案:

答案 0 :(得分:1)

Popen不会阻塞,因此它会在子进程开始时立即返回。作为with语句的最后一行,上下文管理器立即关闭输出文件,这会阻止listener.py写入它。

(更新:在with语句退出后,孩子仍然有自己的打开文件描述符。确切为什么孩子的输出没有被写入文件不明确,但它可能会以某种方式过早退出。)

等待该过程完成:

with open('listenerOutput', 'w') as outfile:
    Popen(["python", "listener.py"], stdout = outfile).wait()

或跳过with语句并稍后手动关闭文件。

fh = open('listenerOutput', 'w')
p = Popen(..., stdout=fh)
# Do some other stuff in the meantime.
p.wait()
fh.close()

答案 1 :(得分:0)

listener脚本可能不会刷新stdout。控制台可能具有自动刷新功能,因此您之前没有注意到。

sys.stdout.flush()write / print之后放置listener.py会刷新输出。

使用类似的Popen设置和打印消息的脚本进行测试,然后等待5秒钟。消息在5秒后出现在文件中,没有刷新,立即显示。