きつねたぬきだし

ちょっとしたメモ代わりに。

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 でやったら非常に深いコールバックだらけになる。