しかし、

しかし、

MacOS 端末のコマンドopenや Window 端末のコマンドをまねるときはstartコメントを付けてください。この回答~/.xsession-errorsたとえば、(bash)にstdoutとstderrを追加することをお勧めします。

alias open='&>>~/.xsession-errors xdg-open'

私が予想する問題は競争条件です。lsof ~/.xsession-errorsこれは、22のプロセスが書き込み用にファイルを開いたままにしたことを示しています。

2つのプロセスが同じオフセットに書き込むのを防ぐ方法は何ですか~/.xsession-errors

答え1

ファイルが追加モードで開くと、オペレーティングシステムはすべての書き込みが最後に行われることを保証します。したがって、あるライターのデータは別のライターのデータを上書きしません。

>>これは、ファイルが追加モード(つまりシェル)で開かれている場合にのみ適用されます。ファイル作成者が次のコマンドを使用してファイルを開いた場合、この保証は適用されず、>次の順序が可能です。

  • プロセス1 >out::現在位置0
  • プロセス2 >>out:現在位置0にあります。
  • プロセス1:書き込みhello、現在位置6
  • プロセス2:書き込みworld、これは位置6に記録されており、プロセス2は現在位置12にあります。
  • プロセス1:書き込みoopsプロセス1のファイルの場所が変更されていないため、場所6に書き込まれます。

Debian では (2001 年頃から) ファイルが.xsession-errors`/etc/X11/Xsession で作成され、追加モードで開かれるので、すべてがうまく動作します。

 exec >>"$ERRFILE" 2>&1

何にログインするのかわかりません~/.xsession-errors

誰もが追加モードでファイルを開くと、すべての出力が表示されます。ただし、出力が断片化される可能性があります。実際、通常のファイルへの十分な小さな書き込みはアトミックです。 512Bより小さいものはどこでも十分に小さくなければならず、Linuxはそれ以上を保証すると思います。したがって、複数の同時ライターがある場合でも、ライターがラインバッファリングされた出力を使用し、ラインが長すぎないと仮定すると、各ログラインは完全に見えるはずです。

1POSIXはパイプ以外のものを保証しません。

答え2

>>使用POSIX シェルはファイルが開かれることを保証します。O_APPEND

Open Group基本仕様7号状態:

ファイル状態フラグが設定されている場合は、各O_APPEND書き込みの前にファイルオフセットをファイルの末尾に設定する必要があり、ファイルオフセット変更と書き込み操作の間に中間ファイル修正操作を行わないでください。

POSIX は、可能な最小バイト数を定義します。必須一枚で書かれたwrite(2)呼ぶ(SSIZE_MAX= 32,767)。戻り値は実際に書き込まれたバイト数です(原子性保証)。

しかし、

すべてのファイルシステムが互換性があるわけではありません。複数のプロセスからファイルに追加説明する:

すべてのファイルシステムがPOSIXと互換性があるわけではないことに注意することが重要です。よく知られている2つの例は、NFSとHDFS(Hadoop分散ファイルシステム)です。これらのネットワークファイルシステムでは、追加がシミュレートされ、競合状態が適用されます。

みんなよく遊ぶわけではありません。

open を使用できますが、O_APPENDファイルに書き込む他のプロセスはそうでない可能性があります。特定のファイルを確認できます。

lsof +fg <file>

心配して走ってみるlsof +fg ~/.xsession-errorsいいえ AP(追加)フラグは、私のリスト(ArchベースのManjaro Linux)の22プロセスがファイルを安全に開くことができないことを示します。

他のシェルで実行している場合にのみ、cat >> ~/.xsession-errors最終出力行に次のAPフラグが含まれます。

cat       3099 ravi    1w   REG   W,AP,LG   0,48      963 1926479 .xsession-errors

この質問を上流でどこに質問するのかを知っている人がいる場合は、コメントを残してください。

ほぼ

すべてのプロセスが次のいずれかを使用してローカルにファイルを開く場合:

  • open(2)そして旗O_APPEND
  • fopen(3)そして"a"
  • POSIXsh >>またはbash &>>

これにより、競合状態でデータを上書きしないでください。

ありがとう@ギルズの答え私に正しい方向を教えてくれました。

関連情報