【问题标题】:How to direct the output of a process to stdout and pipe to another process in bash?如何将进程的输出定向到标准输出并通过管道传输到bash中的另一个进程?
【发布时间】:2020-02-21 12:31:01
【问题描述】:

如何在 bash 中将进程的输出定向到标准输出并通过管道传输到另一个进程?

我在 mac 中使用 bash shell

我有两个python程序generate.pysum.py

generate.py 将整数打印到标准输出。

当使用python3 generate.py 运行时,它会生成

1
2
3
4
...
...

sum.py 只是消耗generate.py 的输出并保持计数器,一旦generate.py 完成sum.py 输出最终值。

但是当我使用以下 bash 命令运行时

python3 generate.py >&2 | python3 sum.py我看不到python3 sum.py的输出

但是如果我这样做python3 generate.py | python3 sum.py 我可以看到sum.py 的结果被打印到标准输出,但我在标准输出中看不到generate.py 的输出。

所以我正在寻找的是查看generate.pysum.py 的输出,同时在它们之间传输数据。有什么想法吗?

【问题讨论】:

    标签: bash


    【解决方案1】:

    使用 tee 命令在 tty 和程序 stdin 之间拆分输出

    echo "hello" | tee /dev/tty | pbcopy
    

    在你的情况下

    python3 generate.py | tee /dev/tty | python3 sum.py
    

    【讨论】:

      【解决方案2】:

      我更喜欢这个命令:

      ( command1 | tee /dev/fd/3 | command2 ) 3>&1
      

      优点是,完整的输出合并到stdout,stderr作为第二个通道仍然完好无损。所以这可以用作函数或脚本,在外部进行通常的重定向。

      翻译成你的命令:

      ( python3 generate.py | tee /dev/fd/3 | python3 sum.py ) 3>&1
      

      【讨论】:

        【解决方案3】:

        你可以这样做

        python3 generate.py | tee /dev/stderr | python3 sum.py
        

        但是“/dev/stderr”和“/dev/tty”都是特殊的“设备文件”,我们应该避免这样使用。

        这更容易用一个例子来说明。如果我们用管道构建一个链式命令,通常的期望是,整个链式管道的行为就像一个单一的连贯命令(整个管道从标准输入获取输入,并将所有输出写入标准输出,错误进入标准错误)。

        如果我在末尾附加“|wc -l”(计算行数),它将期望它返回“generate.py”和“sum.py”的行数。

        但它不会这样工作。

        python3 generate.py | tee /dev/stderr | python3 sum.py | wc -l
        

        wc 输出只会是“1”,它指的是“sum.py”中的单行。

        关于“/dev/tty”,它指的是一个“控制终端”设备文件。您可以参考this 了解更多信息。但本质上这不是一个应该用来生成输出的“设备文件”

        【讨论】:

        • 为什么它很黑?
        • 我更新了我的回复以说明为什么它是 hacky
        猜你喜欢
        • 2018-12-03
        • 2013-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-17
        相关资源
        最近更新 更多