もし私に命令があれば
$ ./script >> file.log
2 回呼び出され、最初の呼び出しが終了する前に 2 回目の呼び出しが行われると、何が起こるでしょうか?
最初の呼び出しは出力ファイルに対して排他ロックを取得しますか? その場合、2 番目のスクリプトは書き込みを試みると失敗しますか、それともシェルは出力を受け入れ (スクリプトを終了させます)、エラーをスローしますか?
それとも、ログ ファイルは 2 回書き込まれるのでしょうか?
答え1
Unix システムでは、一般的に強制ロックは避けられています。カーネルがユーザー プログラムによる変更に対してファイルをロックするケースはいくつかありますが、別のプログラムによって単に書き込まれている場合はロックされません。プログラムがファイルに書き込んでいるという理由でファイルをロックする Unix システムはありません。
スクリプトの同時実行がお互いの邪魔にならないようにするには、次のような明示的なロック機構を使用する必要があります。flock
lockfile
。
追加用にファイルを開くと、>>
各プログラムは常にファイルの末尾に書き込むことが保証されます。そのため、複数のインスタンスの出力が互いに上書きされることはなく、順番に書き込む場合、出力は書き込みと同じ順序になります。
起こり得る悪い事態は、インスタンスの 1 つが出力の複数のチャンクを書き込み、それらが一緒に出力されることを期待している場合です。 1 つのインスタンスによる連続した書き込みの間に、他のインスタンスが独自の書き込みを実行する可能性があります。 たとえば、インスタンス 1 が を書き込みfoo
、次にインスタンス 2 が を書き込みhello
、その後にインスタンス 2 が を書き込む場合bar
、ファイルには が含まれますfoohellobar
。
プロセスは、システムコールを呼び出すときにファイルに書き込みますwrite
。 の呼び出しはwrite
アトミックです。 の呼び出しごとに、write
他のプログラムによって中断されないバイトシーケンスが書き込まれます。 の 1 回の呼び出しで書き込まれるデータの量には制限があることがよくありますwrite
。サイズが大きい場合は、データの先頭のみが書き込まれ、アプリケーションはwrite
再度 を呼び出す必要があります。 さらに、多くのプログラムでは、バッファリング: メモリ領域にデータを蓄積し、このデータを 1 つのチャンクにまとめて書き出します。一部のプログラムでは、完全な行またはその他の意味のある区切りの後に出力バッファをフラッシュします。このようなプログラムでは、行が長すぎない限り (数キロバイトまで。これは OS によって異なります)、行全体が中断されないことが期待できます。プログラムが意味のある場所でフラッシュせず、バッファ サイズのみに基づいてフラッシュする場合、1 つのインスタンスから 4kB、次に別のインスタンスから 4kB、さらに最初のインスタンスから再び 4kB などが表示されることがあります。
答え2
追加を意味する を使用しているため>>
、各インスタンスからの出力の各行は発生した順序で追加されます。
スクリプトの出力がそれぞれ 1 秒の遅延で印刷され、インスタンス 2 が 2.5 秒後に開始された場合、次のようになります1\n
。5\n
1
2
1
3
2
4
3
5
4
5
あなたの質問に答えると、「いいえ」です。