Python subprocess.Popen 通过管道进行通信
我希望能够使用 Popen.communicate
并将标准输出记录到文件中(除了从 communicate()
返回之外)。
这就是我想要的 - 但是这真的是一个好主意吗?
cat_task = subprocess.Popen(["cat"], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
tee_task = subprocess.Popen(["tee", "-a", "/tmp/logcmd"], stdin=cat_task.stdout,
stdout = subprocess.PIPE, close_fds=True)
cat_task.stdout = tee_task.stdout #since cat's stdout is consumed by tee, read from tee.
cat_task.communicate("hello there")
('hello there', None)
这有什么问题吗?看看 communications 的 impl 看起来不错,但是有更好的方法吗?
I want to be able to use Popen.communicate
and have the stdout logged to a file (in addition to being returned from communicate()
.
This does what I want - but is it really a good idea?
cat_task = subprocess.Popen(["cat"], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
tee_task = subprocess.Popen(["tee", "-a", "/tmp/logcmd"], stdin=cat_task.stdout,
stdout = subprocess.PIPE, close_fds=True)
cat_task.stdout = tee_task.stdout #since cat's stdout is consumed by tee, read from tee.
cat_task.communicate("hello there")
('hello there', None)
Any issues with this, looking at communicate's impl it looks good. But is there a nicer way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据您对“更好”的定义,我想说以下内容可能更好,因为它避免了额外的发球流程:
简而言之,它为
communicate()
提供了一个包装器将 stdout 写入您选择的文件句柄,然后返回原始元组供您使用。我省略了异常处理;如果程序更关键,您可能应该添加这一点。另外,如果您希望创建多个Popen
对象并希望它们全部记录到同一个文件,您可能应该将logcommunicate()
安排为线程安全的(同步的)每个文件句柄)。您可以轻松扩展此解决方案以写入 stdout 和 stderr 的单独文件。请注意,如果您希望来回传递大量数据,那么 communicate() 可能不是最佳选择,因为它会在内存中缓冲所有内容。
Depending on your definition of "nicer", I would say that the following is probably nicer in the sense that it avoids having an additional tee process:
In a nutshell, it provides a wrapper for
communicate()
that writes stdout to a file handle of your choice, and then returns the original tuple for you to use. I've omitted exception handling; you should probably add that if the program is more critical. Also, if you expect to create severalPopen
objects and want them all to log to the same file, you should probably arrange forlogcommunicate()
to be thread-safe (synchronised per file handle). You can easily extend this solution to write to separate files for stdout and stderr.Note that if you expect to pass a lot of data back and forth, then
communicate()
might not be the best option since it buffers everything in memory.