空のディレクトリから始めます。
$ touch aFile
$ ls
aFile
次に、2つの引数をls
します。そのうちの1つはこのディレクトリにありません。両方の出力ストリームをoutput
という名前のファイルにリダイレクトします。私が使う >>
同時書き込みを避けるため。
$ ls aFile not_exist >>output 2>>output
$ cat output
ls: cannot access 'not_exist': No such file or directory
aFile
うまくいくようです。このアプローチに危険はありますか?
いいえ、標準の_>>bar 2>&1
_ほど安全ではありません。
あなたが書いているとき
_foo >>bar 2>>bar
_
_O_APPEND
_でbar
ファイルを2回開き、2つの完全に独立したファイルオブジェクト[1]を作成します。それぞれに独自の状態(ポインター、オープンモードなど)があります。
これは、dup(2)
システムコールを呼び出すだけの_2>&1
_とは非常に異なり、stderrとstdoutを同じファイルオブジェクトのエイリアスとして交換可能にします。
今、それに問題があります:
_
O_APPEND
_は、複数のプロセスがファイルにデータを一度に追加する場合、NFSファイルシステムでファイルが破損する可能性があります。これは、NFSがファイルへの追加をサポートしていないため、クライアントカーネルがファイルを追加する必要があるためであり、競合状態なしでは実行できません。
通常、_foo >>bar 2>&1
_のbar
のようなファイルが2つの別々の場所から同時に書き込まれる可能性が非常に低いことを期待できます。しかし、あなたの_>>bar 2>>bar
_によって、何の理由もなくそれを数十桁増やしただけです。
[1] POSIX lingoの「Open File Descriptions」。
するとどうなりますか
some_command >>file 2>>file
file
が2回追加するために開かれるということです。これはPOSIXファイルシステムで安全です。追加用に開かれたときにファイルに行われる書き込みは、データが標準出力ストリームと標準エラーストリームのどちらを経由して送信されたかに関係なく、ファイルの最後で発生します。
これは、基礎となるファイルシステムでのアトミックな追加書き込み操作のサポートに依存しています。 NFSなどの一部のファイルシステムは、アトミック追加をサポートしていません。たとえば、 StackOverflowの質問 "UNIXでファイルがアトミックに追加されていますか?" 。
使用する
some_command >>file 2>&1
nFSでも動作します。
ただし、
some_command >file 2>file
シェルは出力ファイルを切り捨て(2回)、どちらかのストリームで発生する書き込みはoverwriteもう一方によってすでに書き込まれているため、安全ではありませんストリーム。
例:
$ { echo hello; echo abc >&2; } >file 2>file
$ cat file
abc
o
最初にhello
文字列が書き込まれ(終了改行付き)、次に標準エラーから文字列abc
に続いて改行が書き込まれ、hell
が上書きされます。結果は、改行を含む文字列abc
であり、その後に最初のecho
出力の残り、o
および改行が続きます。
その文字列が最後に書き込まれ、echo
文字列より長いため、2つのhello
を傷の周りで交換すると、出力ファイルにabc
のみが生成されます。リダイレクトが発生する順序は重要ではありません。
より慣用的なものを使用する方がより安全です
some_command >file 2>&1
何を達成したいかによります。出力と同じファイルにエラーがあっても問題ないかどうかは、あなた次第です。これは、シェルの機能を使用してテキストをファイルに保存するだけで、必要に応じてリダイレクトできます。 Linuxのすべてがいくつかの方法で実行できるため、これは私のやり方ですls notExistingFile existingFile >> output 2>&1
質問に答える:リダイレクト自体に関しては、はい、完全に安全です。