我说我可以使用a
和b
运行的程序./a
和./b
。
是否可以在不首先写入临时文件的情况下区分输出?
答案 0 :(得分:201)
使用<(command)
将一个命令的输出传递给另一个程序,就像它是一个文件名一样。 Bash将程序的输出传递给管道,并将文件名/dev/fd/63
传递给外部命令。
diff <(./a) <(./b)
同样,如果您想将输入命令,可以使用>(command)
。
这在Bash的手册页中称为“过程替换”。
答案 1 :(得分:25)
添加两个答案,如果要查看并排比较,请使用vimdiff
:
vimdiff <(./a) <(./b)
这样的事情:
答案 2 :(得分:20)
一种选择是使用named pipes (FIFOs):
mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo
...但John Kugelman's solution更清洁。
答案 3 :(得分:14)
对于任何好奇的人,这是您在使用Fish shell:
时执行流程替换的方式<强>击:强>
diff <(./a) <(./b)
<强>鱼:强>
diff (./a | psub) (./b | psub)
不幸的是,鱼的实施目前是deficient; fish将挂起或使用磁盘上的临时文件。您也不能使用psub来输出命令。
答案 4 :(得分:7)
为已经很好的答案添加一点(帮助我!):
命令docker
将其帮助输出到STD_ERR
(即文件描述符2)
我想看看docker attach
和docker attach --help
是否提供了相同的输出
$ docker attach
$ docker attach --help
刚刚输入了这两个命令后,我做了以下内容:
$ diff <(!-2 2>&1) <(!! 2>&1)
!!与-1相同,这意味着在此之前运行命令1 - 最后一个命令
! - 2表示在此之前运行命令2
2&gt;&amp; 1表示将file_descriptor 2输出(STD_ERR)发送到与file_descriptor 1输出相同的位置(STD_OUT)
希望这有一些用处。
答案 5 :(得分:0)
对于zsh,使用=(command)
自动创建一个临时文件,并将=(command)
替换为文件本身的路径。使用常规的进程替换,$(command)
将替换为命令的 output 。
此zsh功能非常有用,可以像使用diff工具一样比较两个命令的输出,例如Beyond Compare:
bcomp =(ulimit -Sa | sort) =(ulimit -Ha | sort)
对于“超越比较”,请注意,由于bcomp
启动比较并等待,因此您必须对以上内容使用bcompare
(而不是bcomp
)。完成。如果使用bcompare
,则会启动比较并立即退出,因此,用于存储命令输出的临时文件将消失。
在此处了解更多信息:http://zsh.sourceforge.net/Intro/intro_7.html
还请注意:
请注意,外壳程序会创建一个临时文件,并在命令完成后将其删除。
,以下是$(...)
和=(...)
之间的区别:
如果您阅读zsh的手册页,可能会注意到<(...)是另一种过程替换形式,类似于=(...)。两者之间有重要区别。在<(...)的情况下,外壳程序将创建一个命名管道(FIFO)而不是文件。这样做会更好,因为它不会填满文件系统。但并非在所有情况下都有效。实际上,如果在上面的示例中用<(...)替换了=(...),除fgrep -f <(...)之外,所有其他代码都将停止工作。您不能编辑管道,也不能将其作为邮件文件夹打开。但是,fgrep从管道中读取单词列表没有问题。您可能想知道为什么diff <(foo)bar不起作用,因为foo | diff-酒吧工作;这是因为diff如果注意到它的参数之一是-,就会创建一个临时文件,然后将其标准输入复制到该临时文件中。