
ちょっとした質問ですが、特殊な文字列で始まるファイルからいくつかの行を抽出し、それをファイルにコピーしようとしています。試したのは次のことです:
cat /dev/ttyACM0 | grep "something" > essai
ファイルは作成されましたが、何も含まれていません。
答え1
効率化のため、grepや他の多くのコマンドではバッファ付きI/Oつまり、一度に大量のデータブロックを読み取り(たとえば、1 文字ずつではなく)、一定量が蓄積されるまでデータを出力しません(たとえば、1 行ずつまたは 1 文字ずつ書き込むのではなく)。
しかし、プログラムの入力が端末(シリアルポートなど)からの場合、オペレーティングシステムはプログラムに有利なように、一度に1行ずつ返します(プログラムは端末を生または非標準モード; ほとんどの人はそうしません。
そしてプログラムが標準入出力ライブラリでは、端末への標準出力 (ドキュメントではこれを「対話型デバイス」と呼びます) は、デフォルトでは行バッファリングされますが、ファイルまたはパイプへの出力は完全にバッファリングされます。
stdioライブラリを使用するプログラムは、フルバッファリング、行バッファリング、またはバッファリングなしを選択することができます。setvbuf
. また、fflush
いつでも書き込みを強制します。
GNU grepは--line-buffered
オプションを選択すると、次のコード一致する行を出力する関数内:
if (line_buffered)
fflush (stdout);
全てのピースをまとめると:
このコマンドを使用すると:
cat /dev/ttyACM0 | grep "something" > essai
cat
は、から 1 行ずつ読み取ります/dev/ttyACM0
。数キロバイトの出力が蓄積された後、パイプに書き込みます。読み取りが 0 カウントを返すか失敗するまで (シリアル ポートがオフラインになるまではおそらく発生しません)、これを繰り返します。
grep
パイプから一度に数キロバイトを読み取り、数キロバイトの出力を蓄積した後、ファイルに書き込みますessai
。読み取りがカウント 0 を返すか失敗するまでこれを繰り返します。これは、プロセスが終了したときに発生しますcat
。
したがって、数キロバイト相当の一致する行が見つかるessai
までは、ファイルには何も表示されません。grep
出力をより迅速にファイルに書き込むには、GNU grep にそのオプションを指定します。
grep --line-buffered < /dev/ttyACM0 > essai
シリアル ポートから読み取るため、行バッファリングされ、--line-buffered
オプションにより出力行もバッファリングされます。