Python 使用 subprocess.Popen 处理管道

Python process pipes with subprocess.Popen

这是一个测试文件:

gunzip -c file_1.gz
Line 1
Line 2
Line 3

我正在以这种方式执行 bash 命令:

cmd = "gunzip -c file_1.gz | grep 3"
subprocess.call(cmd, shell=True))
Line 3

我需要运行 对几个文件并行执行此命令,然后加入进程。所以看来我必须使用 subprocess.Popen().communicate()。但是 Popen 无法正确识别管道并将其提供给第一个命令,在我的例子中是 gunzip:

subprocess.Popen(cmd.split()).communicate())
gunzip: can't stat: | (|.gz): No such file or directory
gunzip: can't stat: grep (grep.gz): No such file or directory
gunzip: can't stat: 8 (8.gz): No such file or directory

我想保留整个命令并避免以这种方式分开它:

gunzip = subprocess.Popen('gunzip -c file_1.gz'.split(), stdout=subprocess.PIPE)
grep = subprocess.Popen('grep 3'.split(), stdin=gunzip.stdout, stdout=subprocess.PIPE)
gunzip.stdout.close()
output = grep.communicate()[0]
gunzip.wait()

有没有办法不分离命令并正确处理管道?

对于 运行 grep 3 命令,您需要上一个命令的输出,因此无法 运行 在使用 subprocess.Popen 的单个命令中成功 运行 .

如果你总是想 运行 grep 3 所有文件,你可以只加入所有 gunzip -c file_x.gz 的结果然后 运行 grep 命令在整个列表中一次。

subprocess.Popen('gunzip -c file_1.gz'.split(), stdout=subprocess.PIPE)
subprocess.Popen('gunzip -c file_2.gz'.split(), stdout=subprocess.PIPE)
...
grep = subprocess.Popen('grep 3'.split(), stdin=all_gunzip_stdout, stdout=subprocess.PIPE)