cmd >out_err.txt 2>out_err.txt
次の例のように、標準出力とエラーを同じファイルにリダイレクトすると、データが失われる可能性があることがわかります。
work:/tmp$ touch file.txt
work:/tmp$ ls another_file.txt
ls: cannot access 'another_file.txt': No such file or directory
上記は例の設定コードです。空のファイルがfile.txt
存在し、another_file.txt
物事ではありません。以下のコードは、out_err.txt
これらのファイルを一覧表示するオペレーティングシステムに入出力を素早くリダイレクトします。
work:/tmp$ ls file.txt another_file.txt >out_err.txt 2>out_err.txt
work:/tmp$ cat out_err.txt
file.txt
t access 'another_file.txt': No such file or directory
エラーストリームに一部の文字が欠落していることがわかります。ただし、>>
valid を使用すると、例を複製するという意味で、出力全体とエラー全体が保存されます。
なぜそしてどのようにcmd >>out_err.txt 2>>out_err.txt
動作しますか?
ベストアンサー1
よく知られているかどうかはわかりませんが、これは2つのファイルハンドルが完全に独立して独立した読み取り/書き込み位置を持つために発生します。だから彼らはお互いを覆うことができます。 (彼らは2つの異なるものに対応します。ファイル説明を開く、残念ながら、「ファイル記述子」という用語と簡単に混同する可能性がある技術用語を使用してください。 )
foo > out.txt 2>out.txt
代わりに、foo > out.txt 2>&1
これはファイル記述子(同じオープンファイルの説明を参照)をコピーするために発生します。
添付するとき、すべて書く作成したファイルの末尾に移動します。これはオペレーティングシステムによってアトミックに処理されるため、他のプロセスも介入できません。したがって、独立した読み書き位置の問題が解決されました。 (ただし、ファイルシステムの制限であるNFSでは動作しないことがあります。)
あなたの例では、エラーメッセージがls: cannot access...
最初にファイルの先頭に書き込まれます。 stderr fdの書き込み場所はファイルの末尾にあります。その後、通常の出力file.txt<newline>
も書き込まれますが、stdout fdの書き込み位置はまだ先頭にあるため、この9バイトにはエラーメッセージの一部が含まれています。
fd が添付されると、何が起こっても 2 番目の書き込みは終了します。