シェルスクリプトからサブシェルを立ちあげて並行化するテスト

ということで、まずは簡単な(ように思える)シェルスクリプトを扱ってみたいと思います。 ぼくはシェルスクリプトについては全くの初心者なのでついでシェルスクリプトそのものも勉強します。

基本

シェルスクリプトからサブシェルを立ちあげて並行で処理させる。
親 parent.sh の中で、子 child.sh を呼び出して、子に処理を行わせつつも、自分の処理も実行するというプログラムを作成します。

■parent.sh

#!/bin/sh

# サブコマンドを実行
sh ./child.sh & # ← 末尾に"&"  をつけてバックグランドにやる。

# サブコマンドに処理をさせつつも、自分の処理も行う。

for i in `seq 1 5`; do
        echo "親の出力 ${i}"
            sleep 1
            done

# サブコマンドが終わるのを待つ
wait

echo "親シェルが終了したよ。

■child.sh

#!/bin/sh

# 子の処理
for i in `seq 1 10`; do
        echo "子の出力  ${i}"
            sleep 0.5
done

echo "子シェルが終了したよ。"

さてこれを実行してみると...

$ sh parent.sh
親の出力 1
子の出力  1
子の出力  2
親の出力 2
子の出力  3
子の出力  4
親の出力 3
子の出力  5
子の出力  6
親の出力 4
子の出力  7
子の出力  8
親の出力 5
子の出力  9
子の出力  10
子シェルが終了したよ。
親シェルが終了したよ。

おお〜 うまく行ったようだ。

ちなみに、末尾の 子シェルを実行しているところで、末尾の & を消して実行すると

子の出力  1
子の出力  2
子の出力  3
子の出力  4
子の出力  5
子の出力  6
子の出力  7
子の出力  8
子の出力  9
子の出力  10
子シェルが終了したよ。
親の出力 1
親の出力 2
親の出力 3
親の出力 4
親の出力 5
親シェルが終了したよ。

と出力されました。これでは並行処理になっていませんね。 親は子の処理が終わるまでブロックされています。

このプログラムのポイントは、

  • シェルスクリプトから単に他のシェルを実行すればサブシェルが立ち上がる。
  • 起動コマンドの末尾に "&" をつけるとサブシェルをバックグラウンドで実行させつつ、自分の処理を続けることができる(並行化)。
  • sleep コマンドでプログラムを一時停止できる。
  • 子シェルの終了を待つには wait をつかう。

あたりでしょうか。