名前付きパイプ
shellで名前付きパイプを使うには mkfifo を使う(mknodでもできるらしい)
- 名前付きパイプの生成
- 読み込み専用で開く
- 書き込みを開始する
- 閉じる
ここで、注意。
読み込み専用で名前付きパイプを開いたら、書き込みが閉じられるまで、その後の処理がブロックされます。
逆に、書き込み専用で開いたら、読み込みが取じられるまで、その後の処理がブロックされてしまいます。
これは、ターミナルを二つ用意し、片方で以下を実行
mkfifo /tmp/test_fifo cat /tmp/test_fifo | perl -nle "s/^/\[\[/;s/$/\]\]/g;print" # このとき、何も表示されず、入力を受けつけない状態になる
もう片方のターミナルで
ls > /tmp/test_fifo
とすると、書き込み処理が終了する為、
先のターミナルのブロックされていた処理が実行されることになる。
(カレントディレクトリのファイル名及びディレクトリ名が「」と「」で囲まれる)
/tmp/test_fifoがプロセスの橋渡しをしているわけです。
というわけで、こんなの作ってみました。
毎度面白くない例ですみません。
_test1(){ # 標準入力を受けとって何らかの処理をする while read n do echo "[[$n]]" done } _test2(){ # 標準入力を受けとって何らかの処理をする while read n do echo "{{$n}}" done } # 名前付きパイプを作成し、バックグラウンドで監視。書き込みがあれば指定したコマンドを実行 mkfifo /tmp/test1_$$ cat /tmp/test1_$$ | _test1 & mkfifo /tmp/test2_$$ cat /tmp/test2_$$ | _test2 & # 名前付きパイプにそれぞれ書き込みを行う for i in * do echo $i >&3 echo $i >&4 done 3>/tmp/test1_$$ 4>/tmp/test2_$$
Linuxで実行すれば、バックグラウンド処理になっているため、_test1と_test2の出力がまざってしまうけど、
OSXでは出力がまざらない。なぜかは未調査。
[追記]この方法で実行すると、_test1 か _test2のどちらかでエラーが発生した場合両方の処理が停止してしまうようだ。