【发布时间】:2013-02-17 20:03:44
【问题描述】:
我有以下似乎可以工作的代码,用于在 python 中将管道与子进程链接在一起,同时逐行读取/写入它们(不预先使用communicate())。该代码只是调用一个 Unix 命令 (mycmd),读取其输出,然后将其写入另一个 Unix 命令 (next_cmd) 的标准输入,并将最后一个命令的输出重定向到一个文件。
# some unix command that uses a pipe: command "a"
# writes to stdout and "b" reads it and writes to stdout
mycmd = "a | b"
mycmd_proc = subprocess.Popen(mycmd, shell=True,
stdin=sys.stdin,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# nextCmd reads from stdin, and I'm passing it mycmd's output
next_cmd = "nextCmd -stdin"
output_file = open(output_filename, "w")
next_proc = subprocess.Popen(next_cmd, shell=True,
stdin=subprocess.PIPE,
stdout=output_file)
for line in iter(mycmd.stdout.readline, ''):
# do something with line
# ...
# write it to next command
next_proc.stdin.write(line)
### If I wanted to call another command here that passes next_proc output
### line by line to another command, would I need
### to call next_proc.communicate() first?
next_proc.communicate()
output_file.close()
这似乎有效,它只在命令末尾调用communicate()。
我正在尝试扩展此代码以添加另一个命令,以便您可以这样做:
mycmd1 | mycmd2 | mycmd3 > some_file
含义:逐行,从 Python 读取 mycmd1 的输出,处理该行,将其馈送到 mycmd2,读取 mycmd2 的输出并逐行 处理它并馈送将其发送到 mycmd3,后者又将其输出放入some_file。这是可能的还是必然会以死锁/阻塞/未刷新的缓冲区结束?请注意,我不只是将三个 unix 命令作为管道调用,因为我想在其间使用 Python 进行干预,并在将每个命令的输出提供给下一个命令之前逐行对其进行后处理。
我想避免调用通信并将所有输出加载到内存中 - 而我想逐行解析它。谢谢。
【问题讨论】:
-
你看过手册中的这个例子吗? docs.python.org/2/library/…
-
@zigg:当然,但它没有回答问题。我不只是制作管道,我想从一个管道读取并写入另一个管道,而不仅仅是调用恰好制作管道的 unix 命令。对我来说重要的是要知道在读/写块或未刷新的缓冲区时会发生什么。
-
我很抱歉;你说得对。我应该更仔细地阅读你的问题。
标签: python unix subprocess pipe