ファイルがありますが、test.txt
名前がtest
。私が試したとき
ls test test.txt > new 2>new
使われなかったのでnew
上書きすると予想しました。>>
しかし、出力ファイルにこれら2つの内容を追加しました。なぜですか?
ベストアンサー1
長い話を短く bash
何でも書き込み前に関連するすべてのファイルを開いて切り取ります。印刷開始時にファイルが切り捨てられたため(2回)、両方とも転送されstdout
ます。stderr
new
bash
ls
これがbash
I / Oリダイレクトの準備/処理方法です。コマンドを>
ファイルにリダイレクトするように要求すると、デフォルトでファイルが開き、bash
必要に応じて生成されます。ファイルがすでに存在する場合は切り捨てられます。あなたの場合、これはopen
システムコールといくつかのフラグを介して行われます。
open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)
O_CREAT
ファイルがない場合は作成し、O_TRUNC
あれば切り捨てます。このシステムコールはopen
リダイレクト初期化の一部です。つまり、次のような複数のリダイレクト操作を使用する場合...bash
$ ls test test.txt > new 2>new
...bash
すべての関連ファイルを開くことから始めます。したがって、実行する前に同じフラグで2回開きますls
。new
open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)
open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)
つまり、デフォルトでコマンドを実行すると、次のbash
操作が順番に実行されます。
- 標準出力として開き、
new
必要に応じてファイルを作成/切り捨てます。 - 標準エラーで開き、
new
必要に応じてファイルを作成/切り捨てます。 - 実行
ls
:内容を作成しますnew
。
ご覧のとおり、関連bash
するすべてのファイルが切り捨てられます。今後start を使用してls
何かを実行するときを意味します。... >new 2>new
new
それから、出力はその位置にリダイレクトされます。必要な動作をするには、stdoutとstderrを独立してbash
キャプチャしls
、書き込み前に1つずつ開く必要があります。オリジナル:
- 開始
ls
。 - 何が起きたら
stdout
開いて切ってnew
使ってください。 - 何が起こったら、
stderr
もう一度開いてカットしてnew
書いてください。
ただし、メッセージは互いに絡み合っている可能性があります。リダイレクトされたプログラムはに何かを書き、stdout
他のものに書き込んstderr
でから戻ってきますstdout
。これらすべてを管理するのは恐ろしいでしょう。(これは望ましくない(定義されていませんか?)動作を引き起こす可能性があります...)。