如何区分两个命令的输出?

我曾想象过比较两个相似目录内容的最简单方法就是这样

diff `ls old` `ls new` 

但我明白为什么这不起作用; diff在命令行上传递了一大堆文件,而不是我希望的两个流。 如何直接将两个输出传递给diff?

命令替换`…`将命令的输出替换为命令行,因此diff将两个目录中的文件列表视为参数。 你想要的是diff在其命令行上看到两个文件名,并让这些文件的内容成为目录列表。 这就是过程替换的作用。

 diff <(ls old) <(ls new) 

diff的参数看起来像/dev/fd/3/dev/fd/4 :它们是对应于bash创建的两个管道的文件描述符。 当diff打开这些文件时,它将连接到每个管道的读取端。 每个管道的写入侧连接到ls命令。

鱼壳

在Fish shell中你必须管道进入psub 。 以下是与Beyond Compare的 Heroku和dokku配置比较示例:

 bcompare (ssh me@myapp.pl dokku config myapp | sort | psub) (heroku config -a myapp | sort | psub) 

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

所以有三种选择:

  1. 命令换人: $(...)
  2. 流程替换: <(...)
  3. zsh-flavvored Process Substitution: =(...)

zsh风格的进程代码#3非常有用,可以像这样用来比较使用diff工具的两个命令的输出,例如Beyond Compare:

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

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

在这里阅读更多:http: //zsh.sourceforge.net/Intro/intro_7.html

另请注意:

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

以下是zsh支持的两种类型的进程替换之间的区别(即#2和#3):

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

参考: https : //unix.stackexchange.com/questions/393349/difference-between-subshel​​ls-and-process-substitution