51

スペースを含むファイルを含むフォルダーを再帰的にループする場合、私が使用するシェルスクリプトは、インターネットからコピーされた次の形式です。

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

IFSビットは理解できたと思いますが、' < <(...)'文字の意味がわかりません。明らかに、ここではある種の配管が行われています。

「<<」や「<(」をグーグルで検索するのは非常に難しいです。「山かっこ」と「小かっこ」を試しましたが、何も見つかりませんでした。

4

3 に答える 3

58

<()マニュアルではプロセス置換と呼ばれ、パイプに似ていますが、/dev/fd/63stdinを使用する代わりにフォームの引数を渡します。

<コマンドラインで指定されたファイルから入力を読み取ります。

一緒に、これらの2つの演算子はパイプのように機能するため、次のように書き直すことができます。

find /bar -name *foo* -print0 | while read line; do
  ...
done
于 2010-03-14T18:00:18.087 に答える
14

<(コマンド)はプロセス置換です。基本的に、「名前付きパイプ」と呼ばれる特別なタイプのファイルを作成し、コマンドの出力を名前付きパイプにリダイレクトします。したがって、たとえば、非常に大きなディレクトリにあるファイルのリストをページングしたいとします。あなたはこれを行うことができます:

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 /は、括弧の間にコマンドの出力があるテキストファイルのように機能します。

于 2010-03-14T22:55:50.633 に答える
4

<stdinにリダイレクトします。

<()ページに記載されているように、ある種の逆パイプのようです。

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

whileループはサブシェルで実行され、ループで行われた変更は失われるため、機能しません

于 2010-03-14T17:57:35.897 に答える