"<<(cmd args)"在shell中意味着什么?

sti*_*tib 31 bash shell built-in

当通过包含空格的文件的文件夹递归循环时,我使用的shell脚本是这种形式,从互联网复制:

    while IFS= read -r -d $'\0' file; do
      dosomethingwith "$file"        # do something with each file
    done < <(find /bar -name *foo* -print0)
Run Code Online (Sandbox Code Playgroud)

我想我理解IFS位,但我不明白' < <(...)'字符是什么意思.显然这里有一些管道.

你知道,谷歌"<<"非常难.

Jos*_*Lee 39

<()在手册中称为进程替换,类似于管道但是传递了表单的参数/dev/fd/63而不是使用stdin.

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

这两个操作符一起完全像管道一样运行,因此可以重写为

find /bar -name *foo* -print0 | while read line; do
  ...
done
Run Code Online (Sandbox Code Playgroud)

  • 如果你不能开始子shell,那就不一样了 (10认同)
  • +1因为您的符号名称正确.正如@knittl指出的那样,它与重写不完全相同,因为循环将在子shell中运行,并且循环对变量所做的任何更改只会影响子shell,而不会影响主脚本.你可以通过将'find'的输出重定向到'`{while ...; 做......; 完成; ......脚本的其余部分......; 使用大括号将整个脚本的其余部分 - 循环和其他材料 - 分组到一个子shell中. (7认同)

Max*_* E. 14

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

ls /usr/bin | more
Run Code Online (Sandbox Code Playgroud)

或这个:

more <( ls /usr/bin )
Run Code Online (Sandbox Code Playgroud)

但不是这个:

more $( ls /usr/bin )
Run Code Online (Sandbox Code Playgroud)

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

~$ 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
Run Code Online (Sandbox Code Playgroud)

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

  • 第二个 shell 应该是 `more &lt; &lt;(ls /usr/bin)`,因为 `&lt;(ls /usr/bin)` 将 stdout 转换为文件并将文件路径作为参数返回,而 ` &lt; ` 接收文件路径并将其转换为标准输入。 (2认同)

kni*_*ttl 5

< 重定向到标准输入。

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

find /bar -name *foo* -print0 | \
while IFS= read -r -d $'\0' file; do
  dosomethingwith "$file"        # do something with each file
done
Run Code Online (Sandbox Code Playgroud)

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