これら2つの「cat」コマンドの結果が異なるのはなぜですか?

これら2つの「cat」コマンドの結果が異なるのはなぜですか?

infileに特定のテキストが含まれていると仮定すると、次のコマンドセットを実行します。

実装する3<infile

猫-n<&3

猫-n<&3

catの最初のインスタンスはファイルの内容を表示しますが、2番目のインスタンスでは何もしません。なぜ違うの?

答え1

同じコマンドのように見えますが、異なる理由は、最初のコマンドの結果としてシステムの状態が変わったためです。具体的には、最初のファイルはファイルcat全体を消費するため、2番目のファイルにはcat読み取る内容が残らず、すぐにEOF(ファイルの終わり)に達した後に終了します。

その理由は、両方の呼び出しでまったく同じファイル記述を使用しているためです(exec < infile作成し、ファイル記述子に割り当てたファイル記述を使用します)。開かれたファイル記述に関連するものの1つはファイルオフセットです。したがって、最初のものは最後にオフセットを維持しながらファイル全体を読み取り、2番目はファイルの最後から読み取ろうとしますが、読み取る内容が見つかりません。3catcat

答え2

@jw013の良い答えに追加すると、それが関連していることに気づくのに役立ちます。

{
   cat -n
   cat -n
} < infile

< fileはい、略語です0< file。つまり、3の代わりにファイル記述子0を使用します。

少し混乱させるために、このバージョンは次のとおりです。

exec 3< infile
cat -n /dev/fd/3
cat -n /dev/fd/3

動作は実行しているオペレーティングシステムによって異なり、タイプinfile一般ファイル対パイプ対デバイス...)

Solarisとほとんどの商用Unicesでは、anはopen("/dev/fd/3")aとある程度同じですdup(3)(したがって、Mayと< /dev/fd/3同じです。<&3/dev/fd/3open("/dev/fd/3")

関連情報