for
の出力に対してを使用して反復しようとしましたがls -R
、ハングします。
for i in $(ls -R /); do echo $i; done;
同じです
for i in $(find /); do echo $i; done;
問題はどこだ?なぜ「カーソルを待機」させるのですか?
一時停止する理由は、最初に$()が最初に計算される変数として扱われるためです。そのため、最初に検索を実行し、それらすべてをメモリにロードしてから、それを繰り返し処理します。
とにかく、検索結果をループすることは悪い考えになる傾向があります。アイテム数が少ない場合でも。bash forループは、すべての空白をアイテムの区切り文字と見なします。これは、ファイル名のいずれかにスペースが含まれていると、望ましくない結果が生じることを意味します。代わりに、findの組み込みexecオプションを使用することをお勧めします。
find / -exec echo '{}' \;
Karthikが指摘したように、読み取りでwhileループを使用することもできます。
ls -R / | while read i; do
echo $i
done
このループは2つの理由で機能します。まず、\ n(またはEOF)でのみブレークを読み取ります。これは、空白のあるファイルが1つのファイルとしてカウントされることを意味します。次に、パイプはデータが蓄積されないようにします。ファイル名は、 lsによって生成されるため、ループによって食われます。
一般に、ls の出力を解析するのはお勧めできません。find の使い方については、他の人がすでに説明しています。bash には globstar という別のオプションがあります。
shopt -s globstar
for file in /tmp/**; do
echo "$file"
done
これは、変数が読み取られ、forにロードされるためです。
時々、bashはそれらの多くの変数を内部的に処理できないことがあります。最良の結果を得るには、これらの代替手段を使用してみてください。
代わりにこれらを試してください:
#IO based is best.
ls -R / | while read i ; do
echo $i
done
(また)
#in your case
find / -exec echo \{\} \;
ループ内で何をしたいかによって異なります。while ループへのパイプの問題は、ループ内の変数の変更が外部に表示されないことです。例えば:
x=0
ls -R / | while read i; do
(( x++ ))
done
echo $x
0 を返します (ちなみに、ksh にはこの問題はありません)。解決策は、名前付きパイプを使用して一度に 1 行ずつフィードするプロセス置換を使用することです。今回はループがインラインで実行されます。
x=0
while read i; do
(( x++ ))
done < <(ls -R /)
echo $x
ksh93 もこの構文をサポートしています