入力ファイルと出力ファイルが同じであれば正確にどうなりますか?

入力ファイルと出力ファイルが同じであれば正確にどうなりますか?

次のコマンドを実行するとします。

tr a-z A-Z < file > file

< fileリダイレクトには、2つのタイプがあります> file。どちらもtrコマンドの前に処理され、私が知っている限り、複数のリダイレクトがある場合は左から右に処理されます。つまり、最初に来るのが< file後に来るのです> file< fileコマンドが実行されると、stdin名前がというファイルから出るという意味ですかfile?その後、その部分> fileが処理されます。これは、出力が名前付きファイルに転送されることを意味しますfile。名前付きファイルもfileサイズが0に切り捨てられます。コマンドは最後に開始されますが(tr例では)、前のステップで入力ファイルが0に切り捨てられたため、空のファイルのみを処理しますか?

答え1

いいですね。>コマンドの開始前にファイルを切り捨てると、コマンドに空の入力ファイルが表示されます。左から右にリダイレクトするのは実際には重要ではありません(ただし、ファイルが存在せず、ファイルが>file <file最初に作成されるとエラーが発生することを除く)。

somecommand <file >>fileほとんどの場合、コマンドは独自の入力を読み取ると無限ループに直面します。ただし、短いファイルの場合、コマンドは内容を書き込む前に入力の終わりを検出できます。この場合、入力と出力は別々のファイルのように動作します。

はいsomecommand <file 1<>file、状況はより複雑です。コマンドがファイルを展開または縮小するかどうかによって、独自の入力を繰り返すことも、そうでない場合もあります。コマンドが常にファイルを折りたたんでいる場合(たとえば、行grep番号付けや色付けなど)、つまり出力のバイトNが常に入力のバイト0..N-1にのみ依存する場合、2つのファイルのように動作します。 。違う。しかし、それに頼ることはお勧めできません。いくつかの点で脆弱であり、コマンドが途中で中断されると混乱を招く可能性があります。

答え2

入力と出力に同じファイルを使用すると、明らかに問題が発生する可能性があります。シェルがこれら2つのファイルを開くと、出力ファイルが切り捨てられるため、問題が発生します。

出力に追加すると、ディスクがいっぱいになるか最大ファイルサイズに達するまで無限に繰り返されます。

関連情報