如何在Linux中将两个命名管道合并为单个输入流

如何在Linux中将两个命名管道合并为单个输入流

使用 Linux 中的管道(|)功能,我可以将标准输入转发到一个或多个输出流。

我可以tee将它拆分为多个子进程。

是否有命令可以合并两个输入流?

我该怎么做? diff 如何工作?

答案1

就我个人而言,这是我最喜欢的(需要 bash 和大多数 Linux 发行版上标准的其他东西)

细节在很大程度上取决于两件事的输出以及你想如何合并它们......

输出中 command1 和 command2 的内容依次为:

cat <(command1) <(command2) > outputfile

或者,如果两个命令都输出您想要并排查看的相同数据的不同版本(我已将其与 snmpwalk 一起使用;一边是数字,另一边是 MIB 名称):

paste <(command1) <(command2) > outputfile

或者如果你想比较两个类似命令的输出(比如在两个不同的目录上查找)

diff <(command1) <(command2) > outputfile

或者,如果它们是某种有序的输出,则合并它们:

sort -m <(command1) <(command2) > outputfile

或者同时运行两个命令(但可能会有点混乱):

cat <(command1 & command2) > outputfile

<() 运算符为每个命令设置一个命名管道(或 /dev/fd),将该命令的输出通过管道传输到命名管道(或 /dev/fd 文件句柄引用)并在命令行上传递名称。 >() 具有等效功能。您可以这样做:command0 | tee >(command1) >(command2) >(command3) | command4例如,同时将一个命令的输出发送到其他 4 个命令。

答案2

您可以使用 将两个蒸汽附加到另一个蒸汽上cat,正如大猩猩所展示的。

您还可以创建一个 FIFO,将命令的输出定向到该 FIFO,然后使用其他程序从 FIFO 读取:

mkfifo ~/my_fifo
command1 > ~/my_fifo &
command2 > ~/my_fifo &
command3 < ~/my_fifo

对于仅写入或读取文件的程序特别有用,或者混合了仅输出 stdout/file 的程序和仅支持另一个的程序。

答案3

(tail -f /tmp/p1 & tail -f /tmp/p2 ) | cat > /tmp/output

/tmp/p1/tmp/p2是输入管道,而/tmp/output是输出管道。

答案4

这里要小心;仅仅对它们进行 cat 操作最终会以你不希望的方式混合结果:例如,如果它们是日志文件,你可能并不希望其中一个行插入另一个行的中间。如果这样可以,那么

tail -f /tmp/p1 /tmp/p2 > /tmp/output

会起作用。如果不是好的,那么你必须找到可以进行行缓冲并仅输出完整行的东西。Syslog 可以做到这一点,但我不确定还有什么可以做到这一点。

编辑:针对非缓冲读取和命名管道进行了优化:

将 /tmp/p1 、 /tmp/p2 、 /tmp/p3 视为命名管道,由“mkfifo /tmp/p

tail -q -f /tmp/p1 /tmp/p2 | awk'{print $0 > "/tmp/p3"; close("/tmp/p3"); fflush();}'&

现在我们可以读取命名管道“/tmp/p3”的输出无缓冲经过 :

尾部-f /tmp/p3

有一个小错误,您需要通过以下方式“初始化”第一个输入管道 /tmp/p1:

echo -n > /tmp/p1

为了得到尾巴首先接受来自第二个管道 /tmp/p2 的输入,而不是等到有东西到达 /tmp/p1 。除非您确定 /tmp/p1 将首先接收输入,否则情况可能并非如此。

还需要 -q 选项,因此尾巴不打印有关文件名的垃圾。

相关内容