気の向くままに辿るIT/ICT/IoT
bash

bash フロー制御サンプル

ホーム前へ次へ
シェル制御構造/条件分岐if...elif...else文/case...esac文/ループwhile...do...done文

bash シェル制御構造サンプル

制御構造サンプル

 コマンドラインから実行できる簡潔に完結したプログラムを特に「ワンライナー」・・・ってか簡潔に完結って・・・クスクス、one-liner...英語の意味は短いジョークかぁ。。。ということは・・・ワンライナーで強引に

$ perl -e 'print "[簡潔に完結]って面白いでしょ!\n"' 

[簡潔に完結]って面白いでしょ! 

って一方的に言い放つこともできるけど、それって人それぞれだろうから、見た人の意見を聞いてみた方がいいよねって話なら

$ [簡潔に完結]は面白いですか? [y/n] 

っていう質問くらいできるようにした方がいいよねってなってPerlもいいけど、ここはbashで書いてみようか、ワンライナーじゃなくていいよねって話になって

sh/bash 条件分岐 if...elif...else文

 bashにはif...elif...else文があるじゃんって言いつつ、elifは要注意だよね、C言語ならelse if、Perlだとくっついちゃう上に1個eなくなってるよって感じでelsif、それがbashとなると更にsまで省略しちゃってelifかよって話だからねって言いながら書いてみると

#!/usr/bin/bash 

# test1.sh 

 echo -n "[簡潔に完結]は面白いですか? [ yes/no/no_comment ] : " 

 read ANSER 

 if [ $ANSER = 'yes' ] 

 then 

 echo "でしょ?でしょー?" 

 elif [ $ANSER = 'no' ] 

 then 

 echo "Oh!My God!!!" 

 echo "(なんで急に外人?回答の選択肢も英語だけど...)" 

 elif [ $ANSER = 'no_comment' ] 

 then 

 echo "................" 

 else 

 echo "選択肢融通きかなくてごめんね" 

 fi 

ってな感じでechoにnオプション付けると改行させないようにできるんだよとか、if文だけじゃないけど{ }で括らなくても書けちゃうんだよとか、行の末尾にセミコロンとか要らないんだよ。

 あとif文の条件のところにある[ ]は、testコマンドの省略形で、もうひとつおまけに[[ ]]とか( )、(( ))っていうのもあるんだけど、実は「 test $ANSER = 'yes' 」とかって書いてもいいんだよとか、「read 文字列」ってやると"文字列"にコマンドライン引数読み込んでくれて、あとで「$文字列」ってやると参照できるんだよとか、if文を閉じる時はfiって書いて改行するんだよとか言いながら、とりあえずファイルに名前付けて実行パーミッションで実行してみよっかって話になって

$ chmod u+x test1.sh 

$ ./test1.sh 

 [簡潔に完結]は面白いですか? [yes/no/no_comment] : 

 お!?出たね?やってみる?いややめとこか?そうだねって話になるとなんで作ったんだっけ?って話になるよね。

 でも、逆にやってみようかって言われると、「!?!?!?」ってなって[ctrl]+[c]で強制終了したら?って言いたくなるよね。

 だって、if...elif...else文だと(むしろ聞かなくていいよって話もあるけど)1回返事すると終わっちゃうとか手抜きがバレちゃうし、やだよねって話になって

sh/bash ループ while...do...done/条件分岐 case...esac文

#!/usr/bin/bash 

# test2.sh 

 while [ : ] 

 do 

 echo "選択肢の数字または文字を入力してください。" 

 echo -n "[簡潔に完結]は面白いですか? [ 1:yes 2:no 3:no_comment 4:q ] : " 

 read ANSER 

 case $ANSER in 

 1|yes|Yes|YES|y|Y ) echo "でしょ?でしょー?" 

 ;; 

 2|no|No|NO|n|N ) echo "Oh!My God!!!" 

 echo "(なんで急に外人?回答の選択肢も英語だけど...)" 

 ;; 

 3|no_comment|no_|no_comm|nc ) echo "................" 

 ;; 

 4|quit|Quit|QUIT|q|Q ) exit 

 ;; 

 * ) echo "うぬ?選択肢が理解できないぞよ" 

 echo "ちなみに入力修正したりしてもこのメッセージ出るよ" 

 ;; 

 esac 

 done 

みたいに、さり気なく選択肢以外の回答にも対応してみちゃったりしてwhileと条件に対して反対の評価するuntil文っていうのもあるんだよとか、case文のセミコロン2つのセット無駄にいっぱいあるように見えるけど必要だからあるんであって削除しちゃダメだよとか、case文を閉じる時はesacって書いて改行するんだよとか言ってみても他ではあんまり見かけないよね。

 あとwhile文の[ : ]の[ ]はさっきも出てきたけどtestコマンドもコロンも実はれっきとしたBourne Shellの組み込みコマンドでコロンは常に真を返すNullコマンドだったりするんだけど普段むやみにwhile [ : ]なんて使って無限ループにならないように気を付けてねとか、適当にecho挟んで見やすくしてねなんて言い逃げして、例の如くとりあえずファイル名付けて実行パーミッション立てて実行してみちゃったりすると

$ chmod u+x test2.sh 

$ ./test2.sh 

 選択肢の数字または文字を入力してください。 

 [簡潔に完結]は面白いですか? [ 1:yes 2:no 3:no_comment 4:q ] : 

なんて出てくるもんだから思わず選択肢にないのに[Quit]って打ったら

 [簡潔に完結]は面白いですか? [ 1:yes 2:no 3:no_comment 4:q ] : Quit 

 あっという間に終わってプロンプトに戻っちゃったりして、なんだったんだろうね?なんて思いながら、実はちょっとこじゃれてる割には全く使い物にならないスクリプトになっちゃってて、そもそも「簡潔に完結」って面白いかどうかなんてどうでもよくなっちゃったりするよね。

shell scriptの汎用性

 この例では、インタプリタのパスをbashにしましたが、bash固有の動作を利用せずshにできれば、sh/bash,csh/tcsh,ksh,zshなど同じ環境でshellを切り替えた際や他の環境におけるshell環境でも利用できる可能性が高まるのでshell scriptの移植性、汎用性が高くなります。

まだある制御構造

 while文は他にもファイルをリダイレクトで入力で読み込むことができたり、for文もスタンダードな記述はもちろんC言語やPerlなどからするとちょっと変わった使い方までできたりします。

 ワンライナーの意味にジョークってあったからとはいえ、このページはかなりぶっちゃけましたが、シェル フロー制御構造をはじめ他では普通に書いてます。

LINK

ホーム前へ次へ