Python子进程.Popen通过管道进行通信 [英] Python subprocess.Popen communicate through a pipeline

查看:304
本文介绍了Python子进程.Popen通过管道进行通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够使用Popen.communicate并将标准输出记录到文件(除了从communicate()返回的文件.

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?

推荐答案

根据您对"nicer"的定义,我认为以下内容可能会更好,因为它避免了额外的tee过程:

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:

import subprocess

def logcommunicate(self, s):
    std = self.oldcommunicate(s)
    self.logfilehandle.write(std[0])
    return std

subprocess.Popen.oldcommunicate = subprocess.Popen.communicate
subprocess.Popen.communicate = logcommunicate
logfh = open("/tmp/communicate.log", "a")

proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
proc.logfilehandle = logfh

result = proc.communicate("hello there\n")
print result

简而言之,它为communicate()提供了一个包装器,该包装器将stdout写入您选择的文件句柄,然后返回原始元组供您使用.我省略了异常处理;您可能应该补充一点,如果程序更关键.另外,如果您希望创建多个Popen对象并希望它们都记录到同一文件中,则可能应该安排logcommunicate()是线程安全的(每个文件句柄同步).您可以轻松扩展此解决方案,以将其写入stdout和stderr的单独文件.

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 several Popen objects and want them all to log to the same file, you should probably arrange for logcommunicate() to be thread-safe (synchronised per file handle). You can easily extend this solution to write to separate files for stdout and stderr.

请注意,如果您希望来回传递大量数据,则communicate()可能不是最佳选择,因为它会缓冲内存中的所有内容.

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.

这篇关于Python子进程.Popen通过管道进行通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆