【问题标题】:Redirect stdout of a subprocess to stdin of 2 or more subprocesses将子进程的标准输出重定向到 2 个或更多子进程的标准输入
【发布时间】:2015-01-02 10:30:01
【问题描述】:

基本上我想学习如何使用stdout 的一个subprocess(比如proc1)作为stdin 的2 个或更多其他subprocesses(比如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 subprocess named-pipes


    【解决方案1】:

    在 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')。

    【讨论】:

    • >>> from subprocess import Popen, PIPE >>> import gzip >>> >>> with gzip.open("cbp12co.csv.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 ... 对于 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() 文件“”,第 10 行 wc.wait() ^ SyntaxError: invalid syntax >>>跨度>
    • 将代码保存到文件中。复制粘贴不适用于普通 Python REPL 中的多行代码
    猜你喜欢
    • 1970-01-01
    • 2013-07-16
    • 2022-12-14
    • 2013-06-02
    • 2016-02-29
    • 1970-01-01
    • 2023-04-05
    • 2011-01-10
    • 2014-11-03
    相关资源
    最近更新 更多