没有临时文件的两个程序的差异输出
Posted
技术标签:
【中文标题】没有临时文件的两个程序的差异输出【英文标题】:Diff output from two programs without temporary files 【发布时间】:2011-04-17 13:03:58 【问题描述】:假设我也有程序 a
和 b
可以使用 ./a
和 ./b
运行。
是否可以在不先写入临时文件的情况下区分它们的输出?
【问题讨论】:
相关:How can I compare the output of two unix commands to find the difference?, How do I diff the output of two commands? 【参考方案1】:使用<(command)
将一个命令的输出传递给另一个程序,就像它是一个文件名一样。 Bash 将程序的输出通过管道传输到管道,并将像 /dev/fd/63
这样的文件名传递给外部命令。
diff <(./a) <(./b)
同样,如果您想将某些内容输入命令,您可以使用>(command)
。
这在 Bash 的手册页中称为“进程替换”。
【讨论】:
需要注意的一个缺点是,如果 ./a 或 ./b 失败,调用者将无法发现。 OP 确实标记了问题 bash,但为了记录,这在任何其他 shell 中都不起作用。它是 Posix 实用程序标准的 bash 扩展。 我用 Java 程序尝试了这个解决方案并得到了这个错误:-bash: syntax error near unexpected token ('
。我再次尝试不带括号并得到-bash: java: No such file or directory
。命令有参数是不是不行?
@DigitalRoss - 该解决方案可以使用别名扩展到其他外壳。在 tcsh 中,以下丑陋有效:alias diffcmd bash -c \'diff \<\(sh -c \!:1\) \<\( sh -c \!:2 \)\'
。 (然后例如:diffcmd "ls" "ls -a")。
对于任何在 Google 之外徘徊的人,这也适用于 zsh。 (此外,如果您需要将输入输入到调用 fseek
的内容中,zsh 提供了 =(./a)
,它可以与 <(./a)
相同地使用,但在后台使用临时文件,zsh 将为您删除。)跨度>
【参考方案2】:
添加两个答案,如果您想查看并排比较,请使用vimdiff
:
vimdiff <(./a) <(./b)
类似这样的:
【讨论】:
vimdiff
创建美观、智能和交互式的差异比较视图。它似乎在大多数系统上都带有vim
包。
vimdiff
不仅会显示不同的行,还会显示不同的特定文本片段。【参考方案3】:
一种选择是使用named pipes (FIFOs):
mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo
...但是John Kugelman's solution 更干净。
【讨论】:
你最好在使用命名管道后删除它们,rm a_fifo b_fifo
。【参考方案4】:
对于任何好奇的人,这是您在使用 Fish shell 时执行进程替换的方式:
重击:
diff <(./a) <(./b)
鱼:
diff (./a | psub) (./b | psub)
不幸的是,目前fish中的实现是deficient; fish 将挂起或使用磁盘上的临时文件。您也不能将 psub 用于命令的输出。
【讨论】:
这目前在鱼中无法正常工作。如果程序的输出大于一个 BUFSIZ,命令将挂起。 (或者鱼实际上只会使用磁盘上的临时文件)【参考方案5】:为已经很好的答案添加更多内容(帮助了我!):
命令docker
将其帮助输出到STD_ERR
(即文件描述符2)
我想看看docker attach
和docker attach --help
是否给出相同的输出
$ docker attach
$ docker attach --help
刚刚输入了这两个命令,我执行了以下操作:
$ diff <(!-2 2>&1) <(!! 2>&1)
!!与 !-1 相同,这意味着在此命令之前运行命令 1 - 最后一个命令
!-2 表示运行前两个命令
2>&1 表示将 file_descriptor 2 输出 (STD_ERR) 发送到与 file_descriptor 1 输出 (STD_OUT) 相同的位置
希望这有一些用处。
【讨论】:
【参考方案6】:对于 zsh,使用=(command)
会自动创建一个临时文件,并将=(command)
替换为文件本身的路径。在正常的进程替换中,$(command)
被替换为命令的输出。
这个 zsh 功能非常有用,可以像这样使用 diff 工具来比较两个命令的输出,例如 Beyond Compare:
bcomp =(ulimit -Sa | sort) =(ulimit -Ha | sort)
对于 Beyond Compare,请注意您必须使用 bcomp
进行上述操作(而不是 bcompare
),因为 bcomp
会启动比较并等待完成。如果您使用bcompare
,则会启动比较并立即退出,因此为存储命令输出而创建的临时文件会消失。
在此处阅读更多信息:http://zsh.sourceforge.net/Intro/intro_7.html
还要注意这一点:
请注意,shell 会创建一个临时文件,并在命令完成时将其删除。
以下是$(...)
和=(...)
的区别:
如果您阅读 zsh 的手册页,您可能会注意到
【讨论】:
以上是关于没有临时文件的两个程序的差异输出的主要内容,如果未能解决你的问题,请参考以下文章