为什么 `sort

为什么 `sort

今天我通过这篇文章学习有关 fifo 的知识:命名管道简介,其中提到cat <(ls -l).

我用 做了一些实验sort < (ls -l),弹出一个错误:

-bash: syntax error near unexpected token `('`

然后我发现我在命令中错误地添加了一个额外的空格。

但是,为什么这个额外的命令会导致这个失败呢?为什么重定向符号必须靠近(

答案1

因为那不是 a <,而是<()完全不同的 a 。这就是所谓的流程替代,它是某些 shell 的一项功能,允许您使用一个进程的输出作为另一个进程的输入。

>运算<符重定向输出和输入文件。操作<()员处理命令(进程),而不是文件。当你跑步时

sort < (ls)

您尝试ls在子 shell 中运行该命令(这就是括号的含义),然后将该子 shell 作为输入文件传递到sort.但是,这不是可接受的语法,您会收到所看到的错误。

答案2

因为事情本来就是这样的。

<(...)inbash是进程替换的语法。它是从 中的同一运算符复制的ksh

<, (, ), |, &,;是特殊的词汇标记,bash用于形成不同组合的特殊运算符。<、、、……<(各有其作用。用于重定向。,将重定向文件中的输入。会重定向来自名为 的文件的输入,但它是一个不同的运算符,不是重定向运算符。<<<&<<file< file<'(file)'(file)<(file)

< (file)<随后将是(file).在这种情况下, in bash,(file)无效。(...)在某些上下文中可以作为单个令牌有效,例如:

(sub shell)
func () {
  ...
}
var=(foo bar)

但不是在

sort < (cmd)

fish外壳中,情况有所不同。 In fish,(...)用于命令替换(相当于$(...)in bash)。用于<输入重定向,就像在类似 Bourne 的 shell 中一样。

所以在fish

sort <(echo file)

将与以下相同:

sort < (echo file)

那是:

sort < file

但这与bash流程替换完全不同。

yashshell 中,另一个 POSIX shell,<(...)不用于流程替代但对于进程重定向

在那里,

sort <(ls -l)

短缺:

sort 0<(ls -l)

是一个重定向运算符。它或多或少相当于:

ls -l | sort

在 中bash<(ls -l)被扩展为管道的路径,所以它更像是:

ls -l | sort /dev/fd/0

在 中zsh(...)被重载为 globbing 运算符((*.txt|*.png)将扩展为txtandpng文件)和 glob 限定符(*(/)例如扩展为目录文件)。

zsh,在:

sort < (ls -l)

(ls -l)将被视为全局限定符。 globl限定符用于匹配链接数量,并期望后面有一个数字l(如ls -ld ./*(l2)列出具有 2 个链接的文件),因此这就是您zsh: number expected在那里收到错误的原因。

sort < (w)会给出一个zsh: no matches found: (w)错误,因为(w)与可写的空名称的文件相匹配。

sort < (w|cat)将对当前目录中的w和/或文件的内容进行排序...cat

相关内容