【问题标题】:Pipe output to two different commands [duplicate]管道输出到两个不同的命令[重复]
【发布时间】:2012-10-17 22:48:21
【问题描述】:

可能重复:
osx/linux: pipes into two processes?

有没有办法将一个命令的输出通过管道传输到另外两个命令的输入中,同时运行它们?

类似这样的:

$ echo 'test' |(cat) |(cat)
test
test

我想这样做的原因是我有一个程序,它从 USB SDR 设备接收 FM 无线电信号,并将音频输出为原始 PCM 数据(如 .wav 文件,但没有标题。)因为信号不是音乐而是 POCSAG 寻呼机数据,我需要将其传送到解码器程序以恢复寻呼机文本。但是我也想听信号,所以我知道是否有任何数据进来。 (否则我无法判断解码器是否损坏或没有数据正在广播。)因此,除了将数据传输到寻呼机解码器之外,我还需要将相同的数据传输到 play 命令。

目前我只知道如何做一个 - 要么将其传输到解码器并静默读取数据,要么将其传输到 play 并在没有看到任何解码文本的情况下听到它。

如何将相同的数据传送到两个命令,以便我可以阅读文本并听到音频?

我不能使用tee,因为它只会将重复的数据写入文件,但我需要实时处理数据。

【问题讨论】:

标签: bash pipe tee


【解决方案1】:

teemkfifo都用应该没问题。

mkfifo pipe
cat pipe | (command 1) &
echo 'test' | tee pipe | (command 2)

【讨论】:

  • 这对于节省 IO 非常有用,例如进行备份。可以在写入之前将tar 输出通过pvsha512sum 进行管道传输,从而避免对磁盘进行两次甚至三次读取/写入。
  • 顺便说一句,因为这会变得非常混乱,如果你想在某个命令上失败,你必须写{ somecommand || errorhandler; } | tee pipe | command2,甚至{ somecommand || errorhandlerforcommand1; } | tee pipe | command2 || errorhandlerforcommand2,因为somecommand || errorhandler | tee pipe | command2和@ 987654330@ 没有像预期的那样处理somecommand 的错误!
  • 最后,将stderr 输入例如日志处理程序,您必须在|| 之前添加2> >(errlogger),如下所示:{ somecommand 2> >(errlogger) || errorhandlerforcommand1; } | tee pipe | command2。其他一切都会在你的脸上爆炸。
【解决方案2】:

最近的 现在的>(command) 语法:

echo "Hello world." | tee >(sed 's/^/1st: /')  >(sed 's/^/2nd cmd: /') >/dev/null

可能返回:

2nd cmd: Hello world.
1st: Hello world.

下载somefile.ext,保存,计算md5sum和sha1sum:

wget -O - http://somewhere.someland/somepath/somefile.ext |
    tee somefile.ext >(md5sum >somefile.md5) | sha1sum >somefile.sha1

wget -O - http://somewhere.someland/somepath/somefile.ext |
    tee >(md5sum >somefile.md5) >(sha1sum >somefile.sha1) >somefile.ext

旧答案

有一种方法可以通过未命名的管道(在 linux 下测试):

 (( echo "hello" |
         tee /dev/fd/5 |
             sed 's/^/1st occure: /' >/dev/fd/4
    ) 5>&1 |
    sed 's/^/2nd command: /'
 ) 4>&1

给:

2nd command: hello
1st occure: hello

此示例将让您下载 somefile.ext,保存它们,计算他的 md5sum 并计算他的 sha1sum:

(( wget -O - http://somewhere.someland/somepath/somefile.ext |
    tee /dev/fd/5 |
    md5sum >/dev/fd/4
  ) 5>&1 |
  tee somefile.ext |
  sha1sum
) 4>&1

【讨论】:

【解决方案3】:

也许看看tee 命令。它所做的只是将其输入打印到文件中,但它也将其输入打印到标准输出。所以像:

echo "Hello" | tee try.txt | <some_command>

将创建一个内容为“Hello”的文件,并让“Hello”(流经管道)最终成为 &lt;some_command&gt; 的 STDIN。

【讨论】:

  • 我不能使用 tee,因为它只会将重复的数据写入文件,但我需要实时处理数据。
  • 也许我误会了你。玩游戏不需要传递原始数据吗?
  • @izomorphius:我需要听到“实时”数据——如果它被重定向到一个文件,会有延迟,所以它不再是实时的。如果我听了很长时间,文件也会变大,直到我用完磁盘空间!
  • 但是您可以使用 tee 将输出重定向到管道。它不一定是文件。
  • @izomorphius:是的,但是我忘记了管道,而你的答案很方便地忽略了这一点:-P
猜你喜欢
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 2011-10-15
  • 1970-01-01
相关资源
最近更新 更多