出力をファイルにリダイレクトすると、ファイルにロックが適用されますか?


30

コマンドがある場合

$ ./script >> file.log

これは2回呼び出され、最初の呼び出しが終了する前に2回目の呼び出しが行われますが、どうなりますか?

最初の呼び出しは出力ファイルの排他ロックを取得しますか?その場合、2番目のスクリプトは書き込みを試みるときに失敗しますか、それともシェルは出力を受け入れ(スクリプトの終了を許可)、エラーをスローしますか?

または、ログファイルが2回書き込まれますか?


1
デフォルトでファイルをロックするシステムは知りません。より可能性が高いのは、2つのプログラムが両方とも追加モードになるため、書き込みをインターリーブすることです。結果はかなり予測不能です。「hello world」の代わりに「hweolrllod」を取得できます。
jw013

回答:


18

>>追加を意味するを使用しているため、各インスタンスからの出力の各行は、発生した順に追加されます。

スクリプト出力が1秒遅れ1\nて出力され5\n、インスタンス2が2.5秒後に開始されると、次のようになります。

1
2
1
3
2
4
3
5
4
5

あなたの質問に答えるために:いいえ。


23

一般に、Unixシステムは強制ロックを回避します。カーネルがユーザープログラムによる変更に対してファイルをロックする場合がいくつかありますが、別のプログラムによって書き込まれているだけの場合はそうではありません。UNIXシステムは、プログラムが書き込み中のためファイルをロックしません。

スクリプトの同時インスタンスがお互いの足の指を踏まないようにする場合は、などの明示的なロックメカニズムを使用する必要があります。flock lockfile

追加のためにファイルを開くと>>、各プログラムは常にファイルの最後に書き込むことが保証されます。そのため、複数のインスタンスの出力は互いに上書きすることはありません。それらが交互に書き込みを行う場合、それらの出力は書き込みと同じ順序になります。

発生する可能性のある悪いことは、インスタンスの1つが出力のいくつかのチャンクを書き込み、それらが一緒に出力されることを期待している場合です。1つのインスタンスによる連続した書き込みの間に、他のインスタンスが独自の書き込みを実行する場合があります。たとえば、インスタンス1が書き込みfoo、次にインスタンス2が書き込み、次にインスタンス2が書き込みhelloのみの場合bar、ファイルにはが含まれますfoohellobar

プロセスは、writeシステムコールを呼び出すときにファイルに効果的に書き込みます。への呼び出しwriteはアトミックです。各呼び出しwriteは、他のプログラムによって中断されない一連のバイトを書き込みます。多くの場合、1回の呼び出しでwrite効果的に書き込むデータの量には制限があります。サイズが大きい場合、データの先頭のみが書き込まれ、アプリケーションはwrite再度呼び出す必要があります。さらに、多くのプログラムがバッファリングを実行します:メモリ領域にデータを蓄積し、このデータを1つのチャンクに書き込みます。一部のプログラムは、完全な行またはその他の意味のある分離の後に出力バッファーをフラッシュします。このようなプログラムを使用すると、行が長すぎない限り(数キロバイトまで。これはOSに依存します)、行全体が中断されないことが期待できます。プログラムが意味のある場所でフラッシュせず、バッファサイズのみに基づいて、1つのインスタンスから4kB、次に別のインスタンスから4kB、次に最初のインスタンスから4kBなどのように表示される場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.