はじめに
ほとんど個人的な実験です。bash の coproc と同等のことを POSIX で標準化された範囲で実装しているだけ(のはず)です。詳細な解説は省きます。
A. パイプを使った一般的な例
当然最速
test1.sh
#!/bin/sh
i=0
while [ "$i" -lt 10000 ]; do
echo "1 / 61"
i=$((i + 1))
done | bc -l
$ time ./test1.sh > /dev/null
real 0m0.039s
user 0m0.060s
sys 0m0.013s
B. 毎回コマンド呼び出しをする場合
当然遅い
test2.sh
#!/bin/sh
i=0
while [ "$i" -lt 10000 ]; do
echo "1 / 61" | bc -l
i=$((i + 1))
done
$ time ./test2.sh > /dev/null
real 0m14.829s
user 0m12.645s
sys 0m5.270s
C. 名前付きパイプを使ったプロセス間通信
そこそこ改善(B. のおよそ 64 倍)
test.sh
#!/bin/sh
mkfifo ./fifo1 ./fifo2
( bc -l ./fifo1 >./fifo2 ) &
i=0
while [ "$i" -lt 10000 ]; do
echo "1 / 61" >&4
read line <&3
echo "$line"
i=$((i + 1))
done 3<./fifo2 4>./fifo1
kill $!
rm ./fifo1 ./fifo2
$ time ./test.sh > /dev/null
real 0m0.230s
user 0m0.153s
sys 0m0.127s
まとめ
とりあえず動くことは確認した。
追記 特に反応ないだろうなーと思っていたのですがちらほら反応があるので、一応説明しておくと、これの目的はパフォーマンスではないです。一つのセッション(プログラム起動)で、そのバックグラウンドで起動したプログラムを終了させずに、プログラムの応答を見つつ命令を送って操作するという使い方を POSIX シェルの範囲で実現可能であることを実証するのが目的です。