このループが空のセットで実行されるのはなぜですか?

このループが空のセットで実行されるのはなぜですか?

空のディレクトリを作成し、次のコードを実行します。

find /empty_directory -mindepth 1 -maxdepth 1 -type d |
while read dir;
do
    echo "Simple find: $dir"
done

printf '%s\n' '-----'                   # Safer than    echo -----

while read dir;
do
    echo "HereDoc find: $dir"
done <<< "$(find /empty_directory -mindepth 1 -maxdepth 1 -type d)"

出力は次のとおりです。

-----
HereDoc find: 

つまり、2番目のループは空の変数を使用して一度実行されます。

なぜこれが起こるのですか?ループオーバーするディレクトリが見つからない場合は、2番目のループが正しく機能して実行されないようにするにはどうすればよいですか?

ベストアンサー1

どうしたの?

特定の問題を解決しようとしていることはわかりますが、デバッグの最初のルールの1つはシーンを単純化することです。そうすれば

$ sleep 1 | read x
$ echo "$?"
1

$ read x <<< $(sleep 1)
$ echo "$?"
0

read空のパイプのaは失敗しますが、nullread文字列のaは成功します(null値を読み取る)。これがあなたが見るものです。

そのスペルは大きな打撃(1):

ここに文字列があります

    Here ドキュメントのバリエーションとして、形式は次のとおりです。

        [n]<<<word

    これwordチルダ拡張、パラメータおよび変数拡張、コマンド置換、算術拡張、および引用符の削除を実行します。パス名の拡張とトークン化は行われません。結果は単一の文字列として提供されます。改行文字を追加 標準入力(またはファイル記述子)のコマンドにn もしn指定)。

      (強調追加)

Bashはここでnull文字列をEOFではなく空行に変換します。

どうすれば修正できますか?

明らかなのは - ループロジックを修正することです:

ディレクトリを読むとき  &&["$dir"! =“”]]
する
    echo "HereDoc 検索: $dir"
完了<<< "$(find /empty_directory -minlength1 -maxlength1 -type d)"
空行を読み取るとループが終了します。

また、明らかなことは、ロジックを修正することです。存在するサイクル:

ディレクトリを読むとき
する
    if ["$dir" = ""]次に続く。
    echo "HereDoc 検索: $dir"
完了<<< "$(find /empty_directory -minlength1 -maxlength1 -type d)"
これは空行を無視しますが、ループを終了しません。

たぶんより良いかもしれません。リダイレクトを編集してください。

ディレクトリを読むとき
する
    echo "HereDoc 検索: $dir"
完璧<<(/empty_directory -minlength1 -maxlength1 -typed 検索)
プロセス置換()と単純リダイレクト()を使用して<(command)<)コマンドの置き換え()の代わりにここでは文字列($(command)<<<)、Bashが改行を追加するのを防ぐことができます。

;PSノートとして()を使用するのと同じように、行末にセミコロンを追加する必要はありませんwhile read dir

おすすめ記事