【问题标题】:Redirect the output of one command to more than one command将一个命令的输出重定向到多个命令
【发布时间】:2013-11-11 17:12:40
【问题描述】:

我知道使用管道可以将命令的输出重定向到另一个命令:

cmd1 | cmd2

当我使用类似的东西时:

cmd1 | cmd2 | cmd3

第二个管道使cmd3 获取cmd2 的输出。我的问题是:是否可以让cmd3 获取cmd1 的输出?

【问题讨论】:

标签: linux bash command-line io-redirection


【解决方案1】:

你可以使用tee:

cmd1 | tee >(cmd2) >(cmd3)

pee:

cmd1 | pee "cmd2" "cmd3"

tee 应该默认安装在所有类 Unix 系统中,而 pee 可以在 moreutils 包中找到。

【讨论】:

  • 很好的解决方案。请注意,tee - 与 pee 不同 - 仍然将 cmd1 的输出也发送到标准输出。警告:使用tee + 进程替换(>(…)) 方法,cmd2cmd3 生成的任何 stdout 输出(如果有)将被不可预测地排序(哪个先出现是不确定的,甚至可能交错)。相比之下,pee 执行命令并因此按照给出命令的顺序产生输出 - 唯一需要注意的是,如果前面的命令挂起,您将看不到后面命令的输出。@987654336 也没有@ 和 pee 仅限于两个目标。
  • 我不确定为什么会发生这种情况,但pee 有时会“失败”:seq 100000 | pee 'head -n1' 'tail -n1'。可能与头部和尾部的工作方式有关..?
【解决方案2】:

您可以使用 tee 和命名管道:

 $ fifo=/tmp/1to3
 $ mkfifo $fifo
 $ cmd1 | tee $fifo | cmd2 & cmd3 <$fifo

【讨论】:

  • 对于像我这样的fifo新手:之后不要忘记删除fifo(命名管道); rm "$fifo" 在这个例子中。请注意,cmd2cmd3 的输出(如果有)将不可预测地交错。要抑制与后台执行相关的内务管理信息 (&amp;),请将整个管道括在括号中。
【解决方案3】:

如果cmd2cmd3保证执行顺序和/或它们的输出保证顺序(如果有)是一个问题,使用流程替换( &gt;(...)) 或命名管道 (FIFO) 不是一个选项。
而是:

  • 使用pee 实用程序,如Radu Radeanu's answer 中所示,如果安装它是一个选项(并且它适用于您的平台)。

  • 否则,使用临时文件如下:

cmd1 | { f=$(mktemp) &amp;&amp; cat &gt;$f; cmd2 &lt;$f; cmd3 &lt;$f; rm $f; }

(在 OSX 上,使用 mktemp -t tmp 而不是只使用 mktempmktemp -t XXXX 在两个平台上都可以使用)。


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 2013-01-12
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    相关资源
    最近更新 更多