バッファが埋まるなり解決してからでないと出力しないコマンドやプログラム、スクリプトは結構見かけます。
タイムアウト設定して閉じてくれればいいのですが、延々と受信待機しているのもあったりして難儀です。
この時、バッファリングしてるモンを適宜吐き出させるコマンドとして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を使っているもので有効……とのこと。
そんなプログラムあるのかとも思いますが……ベアメタルでやってみたとか、何らかの魔界実装だったりしたらダメということです。
参考もと
- stdbufコマンドの使い方: UNIX/Linuxの部屋
- man stdbuf
外部プロセスに依存する処理の場合、GNU paralellも選択肢に入るかも。
shuzo-kino.hateblo.jp