
プログラムが起動すると、システムのどの部分が3つの標準ストリームのバッファリングを設定しますか?
これはLinux、glibc、bashの一部ですか? POSIXは動作を定義しますか、それともCの一部ですか?
Posixにはいくつかの答えがあります。
https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05
プログラムの開始時に、標準入力(標準入力読み取り用)、標準出力(標準出力書き込み用)、および標準エラー(診断出力書き込み用)の3つのストリームが事前定義されているため、明示的に開く必要はありません。オープン時に標準エラーストリームは完全にバッファリングされません。標準入力ストリームと標準出力ストリームは、標準入力ストリームと標準出力ストリームが対話型デバイスを参照していないと判断できる場合にのみ完全にバッファリングされます。
したがって、システムがストリームが対話型でないと判断できる場合は、完全にバッファリングすることができます(stderrを除く)。しかし、実際にこれはシステムのどの部分を決定しますか?
答え1
あなたのプログラミング言語
この動作は、Cランタイムライブラリのアーティファクトであり、Cプログラミング言語の要件です。他のプログラミング言語は歴史的にCランタイムライブラリの上に構築され、この動作はCランタイムライブラリから派生してきました。たとえば、C++ プログラムの場合も同様です。 CおよびC ++言語標準の章は、スタックオーバーフロー(qv)でよく引用されています。
特にPythonで書かれたプログラムは同じ振る舞いをし、しばしば疑問を提起し、時にはプログラミング言語のランタイムの振る舞いが非常に間違っていると非難されます。
プログラムを変更して再コンパイルすることなく、基本言語の意味を使用してプログラムの動作を変更するツールは、2つの形式で提供されています。つまり、ランタイムに自分自身を挿入してバッファリングを変更する言語依存(時にはランタイムライブラリ固有)ツールと変換ツールです。ランタイムライブラリが対話型デバイスであると判断するファイルの標準I / O。後者のカテゴリのツールは、Bernsteinを含む言語に拘束されませんptybandage
。
追加読書
- https://unix.stackexchange.com/a/407472/5132
- https://unix.stackexchange.com/a/249801/5132
- http://git.musl-libc.org/cgit/musl/tree/src/stdio/__stdout_write.c#n8
バッファリングの問題のいくつかの例:
- すぐにPython stdoutをファイルに書き込む
- マイサービスからシステムサービスログをすばやくインポートする
- Systemd Pythonサービスがすべての出力をsyslogに送信しない
- 単一のユニットで実行されるPythonスクリプトの出力は順序がありませんが、シェルは影響を受けないようです。
- Daemontoolsマルチログはログ行の時間情報を失います。どうすれば修正できますか?
- ファイルロガーを使用すると、stderrはstdoutの前にフラッシュされます。
- 単一のユニットで実行されるPythonスクリプトの出力は順序がありませんが、シェルは影響を受けないようです。
- systemd:fork()を使用するプロセスは、子プロセスが終了した後にのみログを表示します。