スペースを含むファイルを含むフォルダーを再帰的にループする場合、使用するシェルスクリプトはこの形式であり、 インターネット からコピーされます。
_ while IFS= read -r -d $'\0' file; do
dosomethingwith "$file" # do something with each file
done < <(find /bar -name *foo* -print0)
_
IFSビットは理解できたと思いますが、「< <(...)
」文字の意味がわかりません。明らかに、ここではある種の配管が行われています。
グーグル「<<」はとても難しいですよね。
<()
は、マニュアルでは プロセス置換 と呼ばれ、パイプに似ていますが、引数を渡しますstdinを使用する代わりに、/dev/fd/63
の形式になります。
<
は、コマンドラインで指定されたファイルから入力を読み取ります。
一緒に、これら2つの演算子はパイプとまったく同じように機能するため、次のように書き直すことができます。
find /bar -name *foo* -print0 | while read line; do
...
done
_<
_はstdinにリダイレクトします。
<()
は、次のページで説明されているように、ある種の逆パイプのようです。
_find /bar -name *foo* -print0 | \
while IFS= read -r -d $'\0' file; do
dosomethingwith "$file" # do something with each file
done
_
whileループはサブシェルで実行され、ループで行われた変更は失われるため、機能しません
<(コマンド)はプロセス置換です。基本的に、「名前付きパイプ」と呼ばれる特別なタイプのファイルを作成し、コマンドの出力を名前付きパイプにリダイレクトします。したがって、たとえば、非常に大きなディレクトリにあるファイルのリストをページングするとします。あなたはこれを行うことができます:
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は、括弧で囲まれたコマンドの出力を含むテキストファイルのように機能します。