假设我有太多的程序 a和 b,我可以运行与 ./a和 ./b。
a
b
./a
./b
有没有可能在不首先写入临时文件的情况下区分它们的输出?
使用 <(command)将一个命令的输出作为文件名传递给另一个程序。Bash 将程序的输出通过管道传递给管道,并将类似 /dev/fd/63的文件名传递给外部命令。
<(command)
/dev/fd/63
diff <(./a) <(./b)
类似地,如果您想通过管道传递某些信息,可以使用 >(command)作为命令。
>(command)
这在 Bash 的手册页中称为“进程替换”。
一种选择是使用 命名管道(FIFO):
mkfifo a_fifo b_fifo ./a > a_fifo & ./b > b_fifo & diff a_fifo b_fifo
但是 约翰 · 库格曼的解决方案更干净。
如果你想看到并列比较的结果,可以使用 vimdiff:
vimdiff
vimdiff <(./a) <(./b)
大概是这样:
在已经很好的答案上再加一点(帮了我!) :
命令 docker将其帮助输出到 STD_ERR(即文件描述符2)
docker
STD_ERR
我想看看 docker attach和 docker attach --help是否给出了相同的输出
docker attach
docker attach --help
$ docker attach
$ docker attach --help
在输入了这两个命令之后,我执行了以下操作:
$ diff <(!-2 2>&1) <(!! 2>&1)
! ! 与!-1相同,这意味着在这个命令之前运行命令1-最后一个命令
2表示在这个命令之前运行命令2
2 > & 1意味着将 file _ criptor 2输出(STD _ ERR)发送到与 file _ description tor 1输出(STD _ OUT)相同的位置
希望这个能派上用场。
对于任何好奇的人来说,下面是使用 鱼壳执行进程替换的方法:
巴斯:
鱼:
diff (./a | psub) (./b | psub)
遗憾的是,fish 中的实现目前是 有缺陷; fish 将挂起或使用磁盘上的临时文件。您也不能使用 psub 作为命令的输出。
对于 zsh,使用 =(command)会自动创建一个临时文件,并用文件本身的路径替换 =(command)。使用正常的进程替换,$(command)被替换为命令的 输出。
=(command)
$(command)
Zsh 特性非常有用,可以像这样使用 diff 工具比较两个命令的输出,例如 Beyond Compare:
bcomp =(ulimit -Sa | sort) =(ulimit -Ha | sort)
对于 Beyond Compare,请注意必须使用 bcomp(而不是 bcompare)完成上述操作,因为 bcomp启动比较,而 等待完成比较。如果使用 bcompare,则启动比较并立即退出,因此为存储命令输出而创建的临时文件将消失。
bcomp
bcompare
阅读更多: http://zsh.sourceforge.net/Intro/intro_7.html
还要注意:
注意,shell 创建一个临时文件,并在命令完成时删除它。
以下是 $(...)和 =(...)的区别:
$(...)
=(...)
如果阅读 zsh 的手册页,您可能会注意到 < (...)是另一种类似于 = (...)的进程替换形式。这两者之间有一个重要的区别。在 < (...)的例子中,shell 创建了一个命名管道(FIFO) ,而不是一个文件。这样更好,因为它不会填满文件系统; 但是它不会在所有情况下都工作。实际上,如果我们在上面的示例中将 = (...)替换为 < (...) ,那么除了 fgrep-f < (...)之外,所有这些方法都会停止工作。您不能编辑管道,也不能将其作为邮件文件夹打开; 但是,fgrep 可以从管道中读取单词列表。您可能想知道为什么 diff < (foo) bar 不工作,因为 foo | diff-bar 工作; 这是因为 diff 创建一个临时文件,如果它注意到它的一个参数是-,然后将其标准输入复制到临时文件。