bash:ループ条件と本文に異なる入力ストリームを使用します。

bash:ループ条件と本文に異なる入力ストリームを使用します。

次のwhileループを持つスクリプトがあります。

while IFS= read -r name; do
    {body}
done < names.txt

ループ条件では、ファイルから名前を読み取る必要がありますが、{body}stdinから読み取る必要があります。上記のスクリプトは{body}ファイルから読み取る必要がありますが、これはエラーです。

他のFDで問題を解決できます。

while IFS= read -r name <&3; do
    {body}
done 3< names.txt

質問:

  1. これが最善の解決策ですか?

  2. ファイル記述子3の使用は安全/推奨されますか? fd番号が高いほど、衝突が発生する可能性は低くなりませんか?

答え1

コマンドに別々のファイル記述子を使用するのがread良い解決策です。

これを行うには、3から9のファイル記述子を使用できる必要があります。シェルはこれを他の目的に使用しません。ファイル記述子0、1、2のみが事前定義された目的を持ちます。可能9より大きい値を持つ記述子を使用することが可能であることがわかりましたが、そのような保証はありません。

これPOSIX規格によると:

開いたファイルは、0 から始まる 10 進数で表されます。ただし、可能な最大値は実装によって定義されます。すべての実装は、アプリケーションで使用できるように少なくとも0〜9(含む)をサポートする必要があります。この数字を「ファイル記述子」と呼びます。0、1、2の値は特別な意味を持ちます。一般的な用途に使用され、特定のリダイレクト操作によって暗示され、それぞれ標準入力、標準出力、および標準エラーと呼ばれます。

9より大きいファイル記述子を使用することは、使用するシェルの数とシェルによっては危険です。

  • bashFD 255は内部で使用されます。
  • zsh、内部的にfd 10を使用dashしてくださいpdksh
  • ksh93fd 3を使用しているようです(ただし、これはバグのようです。現在のファイルシステムのマウントポイントとして使用されているディレクトリに接続しています)。

関連情報