没有临时文件的两个程序的差异输出

Posted

技术标签:

【中文标题】没有临时文件的两个程序的差异输出【英文标题】:Diff output from two programs without temporary files 【发布时间】:2011-04-17 13:03:58 【问题描述】:

假设我也有程序 ab 可以使用 ./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)

同样,如果您想将某些内容输入命令,您可以使用&gt;(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 \&lt;\(sh -c \!:1\) \&lt;\( sh -c \!:2 \)\'。 (然后例如:diffcmd "ls" "ls -a")。 对于任何在 Google 之外徘徊的人,这也适用于 zsh。 (此外,如果您需要将输入输入到调用 fseek 的内容中,zsh 提供了 =(./a),它可以与 &lt;(./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 attachdocker attach --help 是否给出相同的输出

$ docker attach

$ docker attach --help

刚刚输入了这两个命令,我执行了以下操作:

$ diff &lt;(!-2 2&gt;&amp;1) &lt;(!! 2&gt;&amp;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 的手册页,您可能会注意到

【讨论】:

以上是关于没有临时文件的两个程序的差异输出的主要内容,如果未能解决你的问题,请参考以下文章

sql server 永久性备份 临时性备份 有啥区别?

我怎样才能找到临时文件?

技术分享 浅谈 MySQL 的临时表和临时文件

在没有临时配置文件的情况下部署应用程序

错误:无法写入临时文件的块 37583345:设备上没有剩余空间

shell脚本临时文件生成和使用,信号捕捉