【问题标题】:Pipe output to two different commands not interlaced管道输出到两个不交错的不同命令
【发布时间】:2014-07-16 17:58:16
【问题描述】:

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

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

我的问题是这会交织输出。

有没有办法复制标准输出但强制 proc_2 阻塞直到 proc_1 完成?

我在想类似的事情

expensive_command | tee >(proc_1) | wait for EOF | tee >(proc_2) ...

【问题讨论】:

  • 你可以做类似 cmd > file && cat file | tee >(proc_1) && cat 文件 |三通 >(proc_2)

标签: shell pipe stdout tee


【解决方案1】:

您可以将 fifo 用作便宜的锁。完成后让proc1 写入它,并等到从fifo 读取成功后再运行proc2

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

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

【讨论】:

  • 很难在 konsolebox 和 chepner 之间选择一个答案,因为它们都经过深思熟虑,但最后我使用的是 chepner 的解决方案,所以他得到了投票。
  • 虽然您只能选择一个答案,但您仍然可以同时投票。
【解决方案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它运行命令对其标准流进行修改的缓冲操作

【讨论】:

    猜你喜欢
    • 2012-10-17
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多