通过命令管道后比较标准输入

通过命令管道后比较标准输入

我想要以下形式的东西(填空):

cmd1 | ____ cmd2 ____

这与此等效,但不写入任何文件:

cmd1 > temp
cmd2 < temp | diff temp -

cmd1 实际上不是一个命令,它是来自文本编辑器的标准输入流,因此它不能运行多次,因此这不起作用:

diff <(cmd1) <(cmd1 | cmd2)

但这本质上就是我想要的。

我使用的是 macOS,但我更喜欢它与 Linux 兼容。

答案1

一般来说,当你不想写文件时,可以用(命名)管道来替换它,但管道不能同时被两个进程读取。在您的情况下,您可以使用tee拆分输入并为其一端使用命名管道:

mkfifo p
cmd1 | tee p | cmd2 | diff p -
rm p

然而,这有一个主要缺点:管道的缓冲区有限(Linux 上为 64k),因此当 diff 读取其中一个管道与另一个管道进行过多比较时,整个管道将陷入僵局。可以使用buffer至少一个管道的命令来规避该问题:

mkfifo p
cmd1 | tee p | cmd2 | buffer | diff p -
rm p

也可以看看这里对于其他缓冲选项。

死锁的另一个解决方案是使用变量来缓冲其中的整个cmd1输出(将其加载到内存中):

cmd1 | ( b=$(cat); cmd2 <<<"$b" | diff <(echo "$b") - )

相关内容