管道输出到两个不隔行扫描的不同命令

时间:2014-07-16 17:58:16

标签: shell pipe stdout tee

使用此处提到的技术(Pipe output to two different commands),我们可以将stdout拆分为多个进程。

expensive_command | tee >(proc_1) >(proc_2) | proc_3

我的问题是交错输出。

有没有办法复制标准输出但强制proc_2阻止直到proc_1结束?

我在想像

这样的东西
expensive_command | tee >(proc_1) | wait for EOF | tee >(proc_2) ...

2 个答案:

答案 0 :(得分:2)

您可以创建一个缓冲区持有者,一旦输入数据达到eof,就会释放输出,如

expensive_command | awk '{ a[i++] = $0 }END{for (i = 0; i in a; ++i) { print a[i] | "tee temp.txt" } }'

只有awk不支持流程替换。

在bash中你可以这样做:

readarray -t lines <(expressive_command | tee >(proc_1))
printf '%s\n' "${lines[@]}" | tee >(proc_2)

根据您从expressive_command或Bash版本输出的峰值数据大小,该命令可能需要调整。您也可以考虑使用其他语言。

添加:您还可以使用 stdbuf它运行命令,并为其标准流修改缓冲操作。

答案 1 :(得分:2)

你可以使用fifo作为廉价锁。完成后请proc1写入,并等待从fifo读取成功,然后再运行proc2

mkfifo cheap_lock
expensive_command | tee >(proc1; echo foo > cheap_lock) \
                        >(read < cheap_lock; proc2 ) | proc3

(当然,您有责任确保没有其他进程尝试读取或写入cheap_lock。)