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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3800202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:41:39  来源:igfitidea点击:

Diff output from two programs without temporary files

bashfilediff

提问by Verhogen

Say I have too programs aand bthat I can run with ./aand ./b.

假设我有太多程序ab并且可以使用./a和运行./b

Is it possible to diff their outputs without first writing to temporary files?

是否可以在不首先写入临时文件的情况下区分它们的输出?

回答by John Kugelman

Use <(command)to pass one command's output to another program as if it were a file name. Bash pipes the program's output to a pipe and passes a file name like /dev/fd/63to the outer command.

使用<(command)一个命令的输出传递到另一个程序,就好像它是一个文件名。Bash 将程序的输出通过管道传输到管道,并将文件名传递/dev/fd/63给外部命令。

diff <(./a) <(./b)

Similarly you can use >(command)if you want to pipe something intoa command.

同样,>(command)如果要将某些内容通过管道传输命令中,则可以使用。

This is called "Process Substitution" in Bash's man page.

这在 Bash 的手册页中称为“进程替换”。

回答by brokenfoot

Adding to both the answers, if you want to see a side by side comparison, use vimdiff:

添加到两个答案中,如果您想查看并排比较,请使用vimdiff

vimdiff <(./a) <(./b)

Something like this:

像这样的东西:

enter image description here

在此处输入图片说明

回答by martin clayton

One option would be to use named pipes (FIFOs):

一种选择是使用命名管道(FIFO)

mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo

... but John Kugelman's solutionis much cleaner.

...但约翰·库格尔曼的解决方案更简洁。

回答by James McMahon

For anyone curious, this is how you perform process substitution in using the Fish shell:

对于任何好奇的人,这是使用Fish shell执行进程替换的方式:

Bash:

重击:

diff <(./a) <(./b)

Fish:

鱼:

diff (./a | psub) (./b | psub)

Unfortunately the implementation in fish is currently deficient; fish will either hang or use a temporary file on disk. You also cannot use psub for output from your command.

不幸的是,目前在fish 中的实现是有缺陷的;fish 将挂起或使用磁盘上的临时文件。您也不能将 psub 用于命令的输出。

回答by darrenthatcher

Adding a little more to the already good answers (helped me!):

为已经很好的答案添加更多内容(帮助了我!):

The command dockeroutputs its help to STD_ERR(i.e. file descriptor 2)

该命令将docker其帮助输出到STD_ERR(即文件描述符 2)

I wanted to see if docker attachand docker attach --helpgave the same output

我想看看是否docker attachdocker attach --help给出了相同的输出

$ docker attach

$ docker attach

$ docker attach --help

$ docker attach --help

Having just typed those two commands, I did the following:

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

$ diff <(!-2 2>&1) <(!! 2>&1)

$ diff <(!-2 2>&1) <(!! 2>&1)

!! is the same as !-1 which means run the command 1 before this one - the last command

!! 与 !-1 相同,这意味着在此命令之前运行命令 1 - 最后一个命令

!-2 means run the command two before this one

!-2 表示在此之前运行第二条命令

2>&1 means send file_descriptor 2 output (STD_ERR) to the same place as file_descriptor 1 output (STD_OUT)

2>&1 表示将 file_descriptor 2 输出(STD_ERR)发送到与 file_descriptor 1 输出(STD_OUT)相同的地方

Hope this has been of some use.

希望这有一些用处。

回答by Ashutosh Jindal

For zsh, using =(command)automatically creates a temporary file and replaces =(command)with the path of the file itself. With normal Process Substitution, $(command)is replaced with the outputof the command.

对于 zsh, using 会=(command)自动创建一个临时文件并替换=(command)为文件本身的路径。使用正常的进程替换,$(command)替换为命令的输出

This zsh feature is very useful and can be used like so to compare the output of two commands using a diff tool, for example Beyond Compare:

这个 zsh 功能非常有用,可以像这样使用 diff 工具比较两个命令的输出,例如 Beyond Compare:

bcomp  =(ulimit -Sa | sort) =(ulimit -Ha | sort)

For Beyond Compare, note that you must use bcompfor the above (instead of bcompare) since bcomplaunches the comparison and waitsfor it to complete. If you use bcompare, that launches comparison and immediately exits due to which the temporary files created to store the output of the commands disappear.

对于 Beyond Compare,请注意您必须使用bcompfor 上面(而不是bcompare),因为bcomp启动比较并等待它完成。如果使用bcompare,则会启动比较并立即退出,因此创建的用于存储命令输出的临时文件消失了。

Read more here: http://zsh.sourceforge.net/Intro/intro_7.html

在此处阅读更多信息:http: //zsh.sourceforge.net/Intro/intro_7.html

Also notice this:

还要注意这一点:

Note that the shell creates a temporary file, and deletes it when the command is finished.

请注意,shell 创建了一个临时文件,并在命令完成后将其删除。

and the following which is the difference between $(...)and =(...):

并且其之间的差以下$(...)=(...)

If you read zsh's man page, you may notice that <(...) is another form of process substitution which is similar to =(...). There is an important difference between the two. In the <(...) case, the shell creates a named pipe (FIFO) instead of a file. This is better, since it does not fill up the file system; but it does not work in all cases. In fact, if we had replaced =(...) with <(...) in the examples above, all of them would have stopped working except for fgrep -f <(...). You can not edit a pipe, or open it as a mail folder; fgrep, however, has no problem with reading a list of words from a pipe. You may wonder why diff <(foo) bar doesn't work, since foo | diff - bar works; this is because diff creates a temporary file if it notices that one of its arguments is -, and then copies its standard input to the temporary file.

如果您阅读 zsh 的手册页,您可能会注意到 <(...) 是另一种类似于 =(...) 的进程替换形式。两者之间有一个重要的区别。在 <(...) 的情况下,shell 创建命名管道 (FIFO) 而不是文件。这样更好,因为它不会填满文件系统;但它并不适用于所有情况。事实上,如果我们在上面的例子中用 <(...) 替换 =(...),除了 fgrep -f <(...) 之外,所有这些都会停止工作。您不能编辑管道,也不能将其作为邮件文件夹打开;但是,fgrep 从管道中读取单词列表没有问题。您可能想知道为什么 diff <(foo) bar 不起作用,因为 foo | diff - 酒吧作品;这是因为如果 diff 注意到其参数之一是 - ,则会创建一个临时文件,然后将其标准输入复制到临时文件。