パイプから読み取るとawkが完全にバッファリングされるのはなぜですか?

パイプから読み取るとawkが完全にバッファリングされるのはなぜですか?

nmea文字列を送信するGPSデバイスに接続されているシリアルポートからデータを読み込んでいます。

私のポイントを説明するための簡単な呼び出しは次のとおりです。

  $ awk '{ print $0 }' /dev/ttyPSC9 
  GPGGA,073651.000,6310.1043,N,01436.1539,E,1,07,1.0,340.2,M,33.3,M,,0000*56
  $GPGSA,A,3,28,22,09,27,01,19,17,,,,,,2.3,1.0,2.0*39
  $GPRMC,073651.000,A,6310.1043,N,01436.1539,E,0.42,163.42,070312,,,A*67
  GPGGA,073652.000,6310.1043,N,01436.1540,E,1,07,1.0,339.2,M,33.3,M,,0000*55
  $GPGSA,A,3,28,22,09,27,01,19,17,,,,,,2.3,1.0,2.0*39

パイプから読み取ろうとすると、awkは入力をstdoutに送信する前にバッファリングします。

$ cat /dev/ttyPSC9 | awk '{ print $0 }'
<long pause>
GPGGA,073651.000,6310.1043,N,01436.1539,E,1,07,1.0,340.2,M,33.3,M,,0000*56
$GPGSA,A,3,28,22,09,27,01,19,17,,,,,,2.3,1.0,2.0*39
$GPRMC,073651.000,A,6310.1043,N,01436.1539,E,0.42,163.42,070312,,,A*67
GPGGA,073652.000,6310.1043,N,01436.1540,E,1,07,1.0,339.2,M,33.3,M,,0000*55
$GPGSA,A,3,28,22,09,27,01,19,17,,,,,,2.3,1.0,2.0*39

バッファリングを防ぐ方法は?

編集する:Kyle Jonesはcatが出力をバッファリングしていると提案しましたが、これは起こらないようです。

$ strace cat /dev/ttyPSC9 | awk '{ print $0 }'
write(1, "2,"..., 2)                    = 2
read(3, "E"..., 4096)                   = 1
write(1, "E"..., 1)                     = 1
read(3, ",0"..., 4096)                  = 2

考えてみると、プログラムは端末に書き込むときにラインバッファリングを使用し、他のすべての場合は「通常バッファリング」を使用するようです。それでは、猫はなぜそれ以上のバッファリングを実行しないのですか?シリアルポート信号はEOFですか?では、なぜ猫は終了しないのですか?

awkはmawk 1.2です。

ベストアンサー1

私はこれが古い質問であることを知っていますが、ここでそれを探している人には、次の文が役に立つかもしれません。

cat /dev/ttyPSC9 | awk '{ print $0; system("")}'

system("")動作し、POSIXと互換性があります。 Non-posixシステム:注意してください。

同じことを行うより具体的な関数が存在しますfflush()が、以前のバージョンのawkでは使用できません。

重要なメッセージが来ます。文書使用情報system(""):

gawk は system() 関数のこれらの使用を特別なケースとして扱い、空のコマンドでシェル (または他のコマンドソルバー) を実行しないほどスマートです。したがって、gawkにとって、このイディオムは役に立つだけでなく効率的です。

おすすめ記事