シェルスクリプトを書いている時、実行している人に複数ある処理のうちの1つを選んでもらいたい、なんて事がよくありませんか? 例えば、
* yes だったら、あるファイルを削除
* no だったら、何もしない
のような時、どのように書けば良いのでしょうか?
対話処理をするにはreadコマンドが一般的です。LinuxOS等にログインしシェルに打ち込んでみましょう。
$ read MAGICA
※ $はプロンプトの意味なので打たないでね!
readコマンドを打ち込みEnterを押すと、プロンプトが返ってきません。ここで好きな文字列を入力します。例えば、
Mami
と入力してみます。これで MAGICA という変数に Mami という文字列が代入されました。
本当に代入されたのかどうか確認してみましょう。変数名の頭に $ を付けてechoコマンドで確認します。
$ echo $MAGICA
※ $はプロンプトの意味なので打たないでね!
次のように表示されれば成功です。
Mami
シェルスクリプトに限らず、条件によって処理を分岐するには if文 が有名かつ汎用性がありますが、今回はスマートな書き方として case文 を使います。これもまたシェルに打ち込んでみましょう。
1 2 3 4 5 6 7 8 9 | $ case $MAGICA in
Mami)
echo 'last name of Mami is Tomoe.'
;;
*)
echo 'MAGICA is none.'
;;
esac
※ $はプロンプトの意味なので打たないでね!
|
では、実際に yesと打ち込むと”tyeped yes.”、noと打ち込むと”tyeped no.”と出力するようなスクリプトを書いてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #!/bin/sh
echo "Type yes or no."
read answer
case $answer in
yes)
echo -e "tyeped yes.\n"
;;
no)
echo -e "tyeped no.\n"
;;
*)
echo -e "cannot understand $answer.\n"
;;
esac
|
でもちょっと待って下さい。yesかno以外の文字列が入力された場合、yesかnoのどちらかが入力されるまで処理を繰り返したくありませんか? 繰り返し処理をさせたい時は、while文を使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #!/bin/sh
while true;do
echo "Type yes or no."
read answer
case $answer in
yes)
echo -e "tyeped yes.\n"
break
;;
no)
echo -e "tyeped no.\n"
break
;;
*)
echo -e "cannot understand $answer.\n"
;;
esac
done
|
実用的に使う為には関数化します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #!/bin/sh
yes_or_no_while(){
while true;do
echo
echo "Type yes or no."
read answer
case $answer in
yes)
echo -e "tyeped yes.\n"
return 0
;;
no)
echo -e "tyeped no.\n"
return 1
;;
*)
echo -e "cannot understand $answer.\n"
;;
esac
done
}
yes_or_no_while
|
さて無事にyesとno以外の文字列が入力された場合は、繰り返しyesかnoを聞くスクリプトが出来上がりました。が、while文はネスト(入れ子構造)になってしまい若干見辛いかなあ、という時があります。
そう、もっとスマートに書く方法があります。関数の中で、同じ関数を呼び出す 再帰呼出し という方法です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/bin/sh
yes_or_no_recursive(){
echo
echo "Type yes or no."
read answer
case $answer in
yes)
echo -e "tyeped yes.\n"
return 0
;;
no)
echo -e "tyeped no.\n"
return 1
;;
*)
echo -e "cannot understand $answer.\n"
yes_or_no_recursive
;;
esac
}
yes_or_no_recursive
|
上で書いていたスクリプトは汎用性を高くする為に、sh(Bourne Shell)で書いていましたが、bashだともう少しかっこいい書き方ができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #!/bin/bash
function yes_or_no_select(){
PS3="Answer? "
while true;do
echo "Type 1 or 2."
select answer in yes no;do
case $answer in
yes)
echo -e "tyeped yes.\n"
return 0
;;
no)
echo -e "tyeped no.\n"
return 1
;;
*)
echo -e "cannot understand your answer.\n"
;;
esac
done
done
}
yes_or_no_select
|