Python subprocess.Popen 通过管道进行通信

标签 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)

如果有任何问题,请查看通信的实现,它看起来不错。但还有更好的方法吗?

最佳答案

根据您对“更好”的定义,我想说以下内容可能更好,因为它避免了额外的发球过程:

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 的单独文件。

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

关于Python subprocess.Popen 通过管道进行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3456692/

相关文章:

python - print() 中的结束 ='...' 键不是线程安全的?

python - 为什么我的 python 脚本在使用子进程时频繁终止?

python - 使用子进程获取输出

python - 如何从 asn1 数据文件中提取数据并将其加载到数据框中?

python - 是否有比 np.where 更快的替代方案来确定索引?

Python 无法与 Minecraft 服务器的子进程通信

python - OSError : [Errno 12] Cannot allocate memory from python subprocess. 调用

c++ - 为什么 _popen 在这里可以工作,而 boost::process 却不能?

c++ - 运行命令时 popen 的间隔是多少以及如何逐行捕获输出?

python - MS Graph/分配许可证 : primitive 'null' value was expected