使用 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 选项,因此尾巴不打印有关文件名的垃圾。