私はプログラム(Ruby で)を書きましたが、うまく動作しました。数行のテキストを出力し、1 分間停止してから、上記の処理を繰り返します。
これは(Mac OS Xのターミナルでは)うまく動作しますが、出力を記録したい場合は、
ruby myscript.rb | tee record.txt
すると、出力が一定量 (おそらく数 KB) に達するまで、出力は画面に表示されません。ただし、これは 5 分または 10 分間画面に何も表示されない (CTRL-C を押してもファイルには何も表示されない) ことを意味する場合があります。
プログラムを変更して出力をフラッシュすることもできますが、アプリは STDOUT への出力に何が使用されているかに関わらないべきだと考えました。そのため、tee
(おそらくオプションを使用して) うまく動作するようにしたり、他のコマンドを使用したり、Bash またはターミナル アプリのオプションにしたりすることはできますか? 方法はありますか?
答え1
アプリは、STDOUT への出力で何が使用されているかについては無関心であるべきだと考えました。
あなたの考えは間違っています。C 言語や C++ 言語を含むいくつかのプログラミング言語のランタイム ライブラリはすべて、ストリームが端末デバイスに接続されているかどうかを検出するかどうかに応じてバッファリングを変更するというセマンティクスを共有しています。
これは多くの場合、言語で定義された部分です。たとえば、C 言語標準では次のように規定されています。
最初に開かれた時点では、標準エラー ストリームは完全にはバッファリングされません。標準入力ストリームと標準出力ストリームは、ストリームが対話型デバイスを参照していないと判断できる場合にのみ、完全にバッファリングされます。
ストリームが端末デバイスに接続されていない場合の通常の選択は、ユニット バッファリング、ライン バッファリング、またはフル バッファリングを選択することです。ユニット バッファリングとライン バッファリングは標準エラーでよく使用され、フル バッファリングは標準出力でよく使用されます。ただし、これは言語によって異なります。
したがって、出力ストリームがパイプであるときに出力が完全にバッファリングされないようにするには、次のようなことを行う必要があります。
- プログラムを自身に書き込み、標準出力行をバッファリング、スマート バッファリング、またはバッファリングなしにします。
- 特定のプログラミング言語のランタイムライブラリをフックするもの、例えば
stdbuf
コマンドもしプログラミング言語が C であるか、C ランタイム ライブラリ (の I/O ストリーム部分) をベースとして使用していること (一部のプログラミング言語では使用されていない)。 ptybandage
プログラムに標準出力が端末であると認識させ、その出力を取得してパイプの書き込み側に送信するようなツールを使用します。
参考文献
答え2
答えを見てくださいhttps://stackoverflow.com/a/11337109/5656721これはよくある問題なので、標準バフまたはアンバッファRuby プログラムでも同様です。