2010-03-14 32 views
17

當通過文件夾包含空格我用的shell腳本是這種形式,從internet複製的文件遞歸循環:「<(cmd args)」在shell中的含義是什麼?

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

我想我明白了IFS位,但我不明白什麼是「 < <(...)'字符的意思。顯然這裏有一些管道。

這很難讓Google「< <」,你看。

+0

難道你不是指「<<」? – reinierpost 2010-03-14 17:51:34

+0

無論如何,「man sh」是你的朋友。 – reinierpost 2010-03-14 17:52:05

+4

它不是'<<',它是'<和'<(...)'運營商,如果我記得沒錯 – 2010-03-14 17:55:37

回答

23

<()在手冊中被稱爲process substitution,類似於管道,但傳遞的格式爲/dev/fd/63而不是stdin。

<從命令行上命名的文件讀取輸入。

一起,這兩個操作員功能完全一樣的管,因此它可以被重寫爲

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

如果您不能啓動一個子shell – knittl 2010-03-14 18:18:28

+6

+1,這是不一樣的,因爲您的符號名稱是正確的。正如@ knittl指出的那樣,它與重寫不完全相同,因爲循環將運行在子shell中,循環中變量所做的任何更改僅影響子shell,而不影響主腳本。你可以通過將'find'的輸出重定向到''{while ...;做...;完成; ...腳本的其餘部分...; }',使用大括號將整個腳本的其餘部分(循環和其他材質)分組到一個子shell中。 – 2010-03-14 18:39:57

+1

謝謝你。我可以感覺到我的頭骨擴展到執行shell腳本的大腦部分。有一個精確的術語谷歌使得它更容易。現在我要去了解一下子shell是什麼。 – stib 2010-03-15 10:46:40

-3

<<運營商引入了here-document,它將另一個命令的輸出作爲第一個命令的輸入。

更新

好了,所以他們必須添加一些東西的外殼,因爲我去年15年前使用過它。
請不要理會。

4

<重定向到標準輸入。

<()似乎是某種反向管道,在頁面上提到:

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

將無法​​正常工作,因爲while循環將在一個子shell執行,你會失去所做的更改在循環中

+0

這個答案會受益於x-ref'流程替換'和一個像http://www.gnu.org/software/bash/manual/bashref.html#Process-Substitution這樣的URL來解釋它。關鍵點是子外殼和對子外殼中的變量所做的更改。處理它的另一種方式是:'find ... | {while ...;做...;完成; ...腳本的其餘部分...; }',使用大括號在一個子shell,而不是僅僅while循環運行的腳本的所有的休息。 – 2010-03-14 18:35:49

3

<(命令)是過程替代。基本上,它創建一個稱爲「命名管道」的特殊類型的文件,然後將該命令的輸出重定向爲命名管道。因此,例如,假設您想要瀏覽特大目錄中的文件列表。你可以這樣做:

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 /不管像文本文件一樣圓括號之間的命令的輸出。

相關問題