Bash 命令 "read" 使用重定向运算符的行为
Bash command "read" behaviour using redirection operator
如果我执行以下命令:
> read someVariable _ < <(echo "54 41")
和:
> echo $someVariable
结果是:54
。
< <
(带空格)是做什么的?
为什么 _
给出 "echo" 命令结果的第一个词?
上面的命令只是示例。
非常感谢
进程替换
正如 tldp.org 解释的那样,
Process substitution feeds the output of a process (or processes) into
the stdin of another process.
所以实际上这类似于将一个命令 stdout 传递给另一个命令,例如echo foobar barfoo | wc
。但请注意:在 [bash 联机帮助页][3] 中,您会看到它被表示为 <(list)
。所以基本上你可以重定向多个(!)命令的输出。
注意:从技术上讲,当您说 < < 时,您指的不是一件事,而是使用单个 < 的两个重定向和来自 <( . . . .).
输出的进程重定向
现在如果我们只进行进程替换会发生什么?
$ echo <(echo bar)
/dev/fd/63
如您所见,shell 创建了输出所在的临时文件描述符 /dev/fd/63
。这意味着 <
将该文件描述符重定向为命令的输入。
非常简单的示例是将两个 echo 命令的输出过程替换为 wc:
$ wc < <(echo bar;echo foo)
2 2 8
所以我们在这里 shell 为括号中发生的所有输出创建一个文件描述符,并将其作为输入重定向到 wc 。正如预期的那样, wc 从两个 echo 命令接收该流,这两个命令本身将输出两行,每行有一个单词,适当地我们有 2 个单词、2 行和 6 个字符加上两个换行符。
旁注:进程替换可以称为 bashism(可在高级 shell 中使用的命令或结构,如 bash,但未由 POSIX) 指定,但它是在 bash 作为 ksh man page 存在之前在 ksh 中实现的。然而,像 tcsh
和 mksh
这样的 shell 没有进程替换。那么我们如何在不进行进程替换的情况下将多个命令的输出重定向到另一个命令呢?分组加管道!
$ (echo foo;echo bar) | wc
2 2 8
实际上这与上面的示例相同,但是,这与进程替换在幕后有所不同,因为我们将整个子 shell 的标准输出和 wc
的标准输入 [链接为管道][5]。另一方面,进程替换使命令读取临时文件描述符。
那么如果我们可以用管道进行分组,为什么我们需要进程替换?因为有时候我们不能使用管道。考虑下面的示例 - 将两个命令的输出与 diff
进行比较(这需要两个文件,在这种情况下我们给它两个文件描述符)
diff <(ls /bin) <(ls /usr/bin)
如果我执行以下命令:
> read someVariable _ < <(echo "54 41")
和:
> echo $someVariable
结果是:54
。
< <
(带空格)是做什么的?
为什么 _
给出 "echo" 命令结果的第一个词?
上面的命令只是示例。
非常感谢
进程替换
正如 tldp.org 解释的那样,
Process substitution feeds the output of a process (or processes) into the stdin of another process.
所以实际上这类似于将一个命令 stdout 传递给另一个命令,例如echo foobar barfoo | wc
。但请注意:在 [bash 联机帮助页][3] 中,您会看到它被表示为 <(list)
。所以基本上你可以重定向多个(!)命令的输出。
注意:从技术上讲,当您说 < < 时,您指的不是一件事,而是使用单个 < 的两个重定向和来自 <( . . . .).
输出的进程重定向现在如果我们只进行进程替换会发生什么?
$ echo <(echo bar)
/dev/fd/63
如您所见,shell 创建了输出所在的临时文件描述符 /dev/fd/63
。这意味着 <
将该文件描述符重定向为命令的输入。
非常简单的示例是将两个 echo 命令的输出过程替换为 wc:
$ wc < <(echo bar;echo foo)
2 2 8
所以我们在这里 shell 为括号中发生的所有输出创建一个文件描述符,并将其作为输入重定向到 wc 。正如预期的那样, wc 从两个 echo 命令接收该流,这两个命令本身将输出两行,每行有一个单词,适当地我们有 2 个单词、2 行和 6 个字符加上两个换行符。
旁注:进程替换可以称为 bashism(可在高级 shell 中使用的命令或结构,如 bash,但未由 POSIX) 指定,但它是在 bash 作为 ksh man page 存在之前在 ksh 中实现的。然而,像 tcsh
和 mksh
这样的 shell 没有进程替换。那么我们如何在不进行进程替换的情况下将多个命令的输出重定向到另一个命令呢?分组加管道!
$ (echo foo;echo bar) | wc
2 2 8
实际上这与上面的示例相同,但是,这与进程替换在幕后有所不同,因为我们将整个子 shell 的标准输出和 wc
的标准输入 [链接为管道][5]。另一方面,进程替换使命令读取临时文件描述符。
那么如果我们可以用管道进行分组,为什么我们需要进程替换?因为有时候我们不能使用管道。考虑下面的示例 - 将两个命令的输出与 diff
进行比较(这需要两个文件,在这种情况下我们给它两个文件描述符)
diff <(ls /bin) <(ls /usr/bin)