bash "< <(command args)" 在 shell 中是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2443085/
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-17 21:48:39  来源:igfitidea点击:

What does "< <(command args)" mean in the shell?

bashshellbuilt-in

提问by stib

When looping recursively through folders with files containing spaces the shell script I use is of this form, copied from the internet:

当递归循环包含包含空格的文件的文件夹时,我使用的 shell 脚本采用这种形式,从Internet复制:

    while IFS= read -r -d $'
find /bar -name *foo* -print0 | while read line; do
  ...
done
' file; do dosomethingwith "$file" # do something with each file done < <(find /bar -name *foo* -print0)

I think I understand the IFS bit, but I don't understand what the '< <(...)' characters mean. Obviously there's some sort of piping going on here.

我想我了解 IFS 位,但我不明白 ' < <(...)' 字符的含义。显然这里有某种管道在进行。

It's very hard to Google "< <", you see.

谷歌“< <”很难,你看。

回答by Josh Lee

<()is called process substitutionin the manual, and is similar to a pipe but passes an argument of the form /dev/fd/63instead of using stdin.

<()在手册中称为进程替换,类似于管道,但传递形式的参数/dev/fd/63而不是使用标准输入。

<reads the input from a file named on command line.

<从命令行命名的文件中读取输入。

Together, these two operators function exactly like a pipe, so it could be rewritten as

一起,这两个运算符的功能完全像一个管道,所以它可以重写为

ls /usr/bin | more

回答by Max E.

<( command ) is process substitution. Basically, it creates a special type of file called a "named pipe," then redirects the output of the command to be the named pipe. So for example, suppose you want to page through a list of files in an extra-big directory. You could do this:

<( command ) 是进程替换。基本上,它创建一种称为“命名管道”的特殊类型的文件,然后将命令的输出重定向到命名管道。例如,假设您要翻阅一个超大目录中的文件列表。你可以这样做:

more <( ls /usr/bin )

Or this:

或这个:

more $( ls /usr/bin )

But NOT this:

但不是这个:

~$ echo $( ls /tmp )
gedit.maxtothemax.436748151 keyring-e0fuHW mintUpdate orbit-gdm orbit-maxtothemax plugtmp pulse-DE9F3Ei96ibD pulse-PKdhtXMmr18n ssh-wKHyBU1713 virtual-maxtothemax.yeF3Jo
~$ echo <( ls /tmp )
/dev/fd/63
~$ cat <( ls /tmp )
gedit.maxtothemax.436748151
keyring-e0fuHW
mintUpdate
orbit-gdm
orbit-maxtothemax
plugtmp
pulse-DE9F3Ei96ibD
pulse-PKdhtXMmr18n
ssh-wKHyBU1713
virtual-maxtothemax.yeF3Jo

The reason for this becomes clear when you investigate further:

当您进一步调查时,原因就很清楚了:

find /bar -name *foo* -print0 | \
while IFS= read -r -d $'##代码##' file; do
  dosomethingwith "$file"        # do something with each file
done

/dev/fd/whatever acts like a text file with the output of the command between the parenthesis.

/dev/fd/whatever 就像一个文本文件,括号之间是命令的输出。

回答by knittl

<redirects to stdin.

<重定向到标准输入。

<()seems to be some sort of a reverse pipe, as mentioned on the page:

<()似乎是某种反向管道,如页面上所述:

##代码##

will not work, because the while loop will be executed in a subshell, and you'll lose changes made in the loop

将不起作用,因为 while 循环将在子 shell 中执行,并且您将丢失循环中所做的更改