python - 将子进程的标准输出重定向到 2 个或更多子进程的标准输入

标签 python subprocess named-pipes

基本上我想学习如何使用一个子进程(例如proc1)的stdout作为stdin python 中的 2 个或多个其他子进程(例如 proc2proc3)。

嗨, 我需要 zcat 一个 .gz 文件,并使用发送到 subprocess.PIPE 的输出来进行 cksum (unix 实用程序)和行计数。

我可以像这样在 bash 中做到这一点...

[hashroot@dev_server 12]$ zcat ABC_C_TPM_26122014.data.gz | tee >(wc -l) >(cksum)| tail -2
2020090579 112180
586

我想在 python 中做同样的事情。

一旦我这样做...

>>> import subprocess
>>> import os
>>> fl123 = 'ABC_C_TPM_26122014.data.gz'
>>> pqr123 = subprocess.Popen(['zcat', fl123], stdout=subprocess.PIPE)
>>> subprocess.check_output(['cksum'], stdin=pqr123.stdout)
b'4286000649 256100 \n'

现在 PIPE 是空的,那么在我不再执行 zcat 之前我将如何获得行数。

我可以通过在子进程中运行 zcat 两次,并将第一个 zcat 输出重定向到 wc -l,将第二个 zcat 输出重定向到 校验和。但 zcat 是基于磁盘 IO 的,速度很慢。所以我想避免它。

最佳答案

在 Python 中实现 tee 命令的一个简单方法是手动写入子进程:

import gzip
from subprocess import Popen, PIPE

# zcat ABC_C_TPM_26122014.data.gz | tee >(wc -l) >(cksum)
with gzip.open("ABC_C_TPM_26122014.data.gz", "rb") as input_file:
    wc = Popen(['wc', '-l'], stdin=PIPE, bufsize=1, close_fds=True)
    cksum = Popen(['cksum'], stdin=PIPE, bufsize=1, close_fds=True)

    line_count = 0
    for line_count, line in enumerate(input_file, start=1):
        wc.stdin.write(line)
        cksum.stdin.write(line)
    wc.stdin.close()
    cksum.stdin.close()
wc.wait()
cksum.wait()
print("Line count in the parent: %d" % line_count)

如果输入中的行可能很大,那么您可以分块读取输入:chunk = input_file.read(chunk_size) 而不是逐行读取 (b'\n' )。

关于python - 将子进程的标准输出重定向到 2 个或更多子进程的标准输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27740689/

相关文章:

python - 编译 Cython 扩展错误 - Pycharm IDE

python - 操作系统和子进程不再在 Windows 10 上找到二进制文件

python - 使用ffprobe在python中查找视频文件长度时如何解决文件路径错误?

.net - 双向命名管道问题

java - Java 中命名管道的并发读/写(在 Windows 上)

python - NoneType-Python 中的 Yield 错误

python - 对 __init__.py 的要求只是为了满足 pylint 和 mypy

python - 在 flask 中禁用自动转义

python - 无法通过子处理捕获 os 错误

c++ - 使用 istream 从命名管道读取