BLOGTIMES
2014/02/14

awk に標準出力をバッファさせないようにする

  Tips awk  sh 
このエントリーをはてなブックマークに追加

vmstat の出力にはタイムスタンプがないので、こんな感じで awk を使ってタイムスタンプをつけていたのですが、これをファイルにリダイレクトして、そのファイルを tail -f で追いかけてみても一向に内容が更新されないという現象が発生して困ってしまいました。

$ vmstat 1 | awk '{print strftime("%Y-%m-%d %T ") $0;}' 2014-02-14 21:12:56 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ 2014-02-14 21:12:56 r b swpd free buff cache si so bi bo in cs us sy id wa st 2014-02-14 21:12:56 2 0 105736 70564 267812 603616 0 0 6 5 0 0 3 1 96 0 0 2014-02-14 21:12:57 0 0 105736 70604 267820 603608 0 0 0 96 1059 499 0 0 100 0 0 2014-02-14 21:12:58 0 0 105736 70604 267820 603608 0 0 0 0 1042 361 0 0 100 0 0

コンソールでは問題ないのに、リダイレクトすると問題が出るというパターンは、これまでにも C 言語の printf()Python でハマった経験から、標準出力のバッファリングの問題に間違いないということで、今日は awk の標準出力のバッファリングを無効にする方法を調べてみました。

system("")がポータビリティが高い?

まず awk には出力バッファを明示的に制御するためのオプションがありません

というわけでバッファを自分で明示的にフラッシュする方法を取ることになります。gawk のマニュアルには出力バッファの制御について解説した下記の文章があり、これによると gawk の場合には明示的に fflush() を呼べば良いが、gawk 依存になってしまうので、system("")を使う方がポータビリティが高いと述べられていました。

The GNU Awk User

Controlling Output Buffering with system()
The fflush() function provides explicit control over output buffering for individual files and pipes. However, its use is not portable to many older awk implementations. An alternative method to flush output buffers is to call system() with a null string as its argument:
system("") # flush output

gawk treats this use of the system() function as a special case and is smart enough not to run a shell (or other command interpreter) with the empty command. Therefore, with gawk, this idiom is not only useful, it is also efficient. While this method should work with other awk implementations, it does not necessarily avoid starting an unnecessary shell. (Other implementations may only flush the buffer associated with the standard output and not necessarily all buffered output.)

そんなわけで、スクリプトを下記のように書き換えることで、バッファが明示的にフラッシュされるようになりました。

$ vmstat 1 | awk '{print strftime("%Y-%m-%d %T ") $0; system("");}'

参考


    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/6516
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    コメントはありません
    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン