Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

stdbufコマンドでバッファリングを無効にする

バッファが埋まるなり解決してからでないと出力しないコマンドやプログラム、スクリプトは結構見かけます。
タイムアウト設定して閉じてくれればいいのですが、延々と受信待機しているのもあったりして難儀です。
この時、バッファリングしてるモンを適宜吐き出させるコマンドとしてstdbufというのがあります。

実際のところ

受信待機中のnetcatからとりあえず文字列を吐き出させるには、以下の様に。

$ netcat -lk localhost 1099 |  stdbuf -i0 xxd -ps

"i0"が入力バッファを無効化するオプション。
なので、上の例ではlocalhost:1099にきたパケットを扱えるようになり次第適宜xxdに送り込むという挙動をします。

manの事例では、cutが処理終わるまでバッファを解放しない件で以下の様に対応できるとのこと。
この場合、"oL"は出力をラインバッファとして扱うようします。

$ tail -f access.log | stdbuf -oL cut -d ' ' -f1 | uniq

試しに実行してみると、同じ内容の時は無視、違う内容なら出力というような面白い挙動をします。
具体的には

~$ cat samplecmd.cmd
deadbeef
deadbeef
1234
1234
98
deadbeef
deadbeef
98

という中身になっているのが

deadbeef
1234
98
deadbeef
98

という出力になります。

また、参考元にある例だとgrepで固まる所を"-o0"でバッファ無しにすることで抜ける技も。

$ tail -f samplecmd.cmd  | stdbuf -o0 grep beef | sed -e "s/dead/live/"
livebeef
livebeef
livebeef
livebeef
livebeef
livebeef

気を付ける:万能というわけでもない

内部でstdioを使っているもので有効……とのこと。
そんなプログラムあるのかとも思いますが……ベアメタルでやってみたとか、何らかの魔界実装だったりしたらダメということです。

参考もと

外部プロセスに依存する処理の場合、GNU paralellも選択肢に入るかも。
shuzo-kino.hateblo.jp