mkfifo と tee で複数の入力・出力のパイプ
はじめに
UNIX では、ほとんどありとあらゆるものをファイルとして扱うことができる。
tee コマンドについて書いてある他ブログ記事を読むと、 「ファイルに書きつつ標準出力に出す」というような 画面上でのログ確認での使い方のみ書いている記事が多い。 もっと広義の「ファイル」には「FIFO」も含む。 FIFO とは名前付きのパイプであり、ファイルとほぼ同じインターフェイスを利用する。
内容
mkfifo と組み合わせて、 2 つの出力を持つパイプを作ってみる。
$ mkfifo input1 $ mkfifo output1 $ mkfifo output2 $ tail -f input1 | tee output1 output2 2>&1 > /dev/null &
このようにすると、 別シェルで立ち上げた
$ echo `date` > input1
が、 output1, output2 の各々の、各々のオープンしているプロセスにパイプする。 このようにして複数の管に分岐する水道管工事ができる。
また、 mkfifo で作ったファイルは、名前にリダイレクトすることで、 複数のプロセスからの書き込みもできる。 複数の管から統合する水道管工事もできる。
メリット
- 実際のファイルと違い容量を気にする必要がない。
- /dev/null に捨てる時のように、追記の ">>" ではなく、 ">" 一個で済む。
- 書き込みをオープンしているプロセスがない場合には適切にブロックされる。
その他
ブロッキング・ノンブロッキング などのより詳しい説明は man 4 fifo 。
同じ意図をより手軽に行うため、 tpipe がある http://linux.die.net/man/1/tpipe
現実にはこんな水道管工事が必要になったことはない。
シェルは文法がアレだけど、 「たった 4 行で完全なマルチプロセス・非同期なストリームを実現する」 と考えると、先人は偉大だと思う。
例えば同じことを Node.JS でやったら非常に深いコールバックだらけになる。