繁体   English   中英

将子流程的stdout重定向到2个或更多子流程的stdin

[英]Redirect stdout of a subprocess to stdin of 2 or more subprocesses

基本上,我想学习如何使用stdoutsubprocess (说proc1为) stdin的2个或多个其他subprocess ES(比如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输出重定向到cksum我可以很好地做到这一点。 但是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' )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM