在shell中,“〈〈(命令参数)”是什么意思?

yhqotfr8  于 2023-01-13  发布在  Shell
关注(0)|答案(4)|浏览(573)

当递归遍历包含空格的文件的文件夹时,我使用的shell脚本的格式如下,它是从internet复制来的:

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

我想我理解了IFS,但是我不理解' < <(...) '字符的意思。显然这里有某种管道。
你看,在谷歌上搜索“〈〈”或“〈(“是很困难的,我试过“尖括号”和“小于括号”,但什么也没找到。

zkure5ic

zkure5ic1#

<()在手册中称为进程替换,类似于管道,但传递/dev/fd/63形式的参数,而不是使用stdin。
<从命令行中名为的文件读取输入。
这两个运算符的作用完全类似于管道,因此可以将其重写为

find /bar -name *foo* -print0 | while read line; do
  ...
done
vdgimpew

vdgimpew2#

〈(命令)是进程替换。基本上,它创建一个特殊类型的文件,称为"命名管道",然后将命令的输出重定向为命名管道。因此,例如,假设您希望在一个超大目录中分页浏览文件列表,您可以这样做:

ls /usr/bin | more

或者这个:

more <( ls /usr/bin )

但不是这个:

more $( ls /usr/bin )

当您进一步调查时,其原因将变得更加清楚:

~$ 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

/dev/fd/whatever的作用类似于一个文本文件,括号中包含命令的输出。

mfuanj7w

mfuanj7w3#

<重定向到标准输入。
<()似乎是某种反向管道,如页面上所述:

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

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

kognpnkq

kognpnkq4#

当您需要将文件传递给命令但使用另一个命令的输出而不是文件时,通常会使用进程替换构造(如https://www.gnu.org/software/bash/manual/html_node/Process-Substitution.html#Process-Substitution所示),从而避免了提前创建和填充该文件的需要。
例如,假设您要比较2个命令的输出,您可以这样做:
diff <(command1) <(command2)

相关问题