条件,ステートメントブロックとif文
BASHスクリプトでの条件式とステートメントブロックについて説明し,それをもとにif文の書き方を説明する.
if文を実行するためには,条件をチェックするための仕組みが必要である.先にスクリプトはexit文で終りたいと書いたのは,その仕組みのためである.以下はcommad1が成功した場合はcommand2を実行するものである.
UNIXの思想の一つにシンプルで小さいものを作るという思想があるらしい.例えばlsがあってlessがあればls | less ができるね,ということである.各プログラムの機能が小さくシンプルなっているからそれらの組み合わせでいろんなことができる,そうすれば,非常に美しい.自分でスクリプトやプログラムを作成する際にも心がけるべきである.そしてその作成したスクリプトを他と組み合わせるためにexit文が必要なのである.
command1 && command2以下は逆にcommand1が成功した後にcommand2を実行するものである.
command1 || command2演算子&&や||がある場合,システムはcommand1の返り値(終了コード)をみてcomman2を実行するかどうかを決める.そしてその返り値はexit文のパラメータである.
UNIXの思想の一つにシンプルで小さいものを作るという思想があるらしい.例えばlsがあってlessがあればls | less ができるね,ということである.各プログラムの機能が小さくシンプルなっているからそれらの組み合わせでいろんなことができる,そうすれば,非常に美しい.自分でスクリプトやプログラムを作成する際にも心がけるべきである.そしてその作成したスクリプトを他と組み合わせるためにexit文が必要なのである.
話がif文から少しそれるが,&&や||で連結するコマンドはそれぞれ一つずつしか書けない.
command1 && command2 ; command3とすると,command3はcommand1 && command2と関係なく実行される.command1が成功した場合に,command2とcommand3を実行するようにしたければ,ステートメントブロック{}で囲う.
command1 && { command2 ; command3; }
;に注意.command2とcommand3の間はまず必要.で,command3と}も必要(スクリプトファイルでは;を書く代わりに改行した方が見やすいと思う).
話をもどして,条件をチェックするための仕組みとしてtestコマンドがある.testコマンドは[ ](間にスペースが必要)と書くことができる(man [とか,man [ ]とするとtestコマンドのmanが出て来る).testコマンドはファイルやディレクトリの有無,算術比較,文字列比較の結果を返す.以下の二つの例は等価である(後者はスペースに注意).
test -d hoge && echo true || echo false [ -d hoge ] && echo true || echo false上記の両者は./hogeというディレクトリが存在すればtrue,そうでなければfalseをechoする.testコマンドは他にもいろいろな条件チェックができるがmanに書いてあるのでここでは述べない.
if文は複雑な条件分岐を表現するのに使用する.また,条件分岐があるコードの可読性が増す(と思う).
test -d hoge && echo true || echo falseはecho falseが実行される条件がtest -d hogeの結果なのか,echo trueの結果なのか不安になったりする.この例をif文を使用して書くと,以下のようになる.
if test -d hoge then echo true else echo false fiif文のキーワードはif,then,else,elif,fiである.elifを使用した例を以下に示す.今度はtestの代わりに[ ]を使用する.
if [ -d hoge ] then echo hoge is a directory elif [ -f hoge ] then echo hoge is a file else echo hoge : no such a file or directory fiecho hoge is a fileはtest -d hogeに失敗しかつtest -f hogeに成功した場合にのみ実行される.ifやelifの条件部はtestコマンドでなくてもよい.以下に例を示す.
if mount /cdrom &>/dev/null then echo mount succeeded else echo mount failed fiこの例では,mountコマンドの終了コードによって,次の処理を決定する.if文の構文を以下に示す.
if A then B elif A then B else B fiAとBは一つ以上の代入文,コマンド,if文,while文等である.ただし,条件判定に使用されるのは,Aの最後の実行文である.
if commandA ; command B then echo B succeeded fiこの例では,commandAが成功しようがしまいがcommandBが実行される.そして,commandBの終了コードがif文の条件判定に使用される.また,条件部にもif文やwhile文を使用できる.
if if ls hoge &>/dev/null ; then echo A ;else echo B ; fi then echo hoge exists fiこの場合,正しい結果が表示されない.hogeが存在使用がしまいが,if ls hoge &>/dev/null ; then echo A ;else echo B ; fiは成功するので,echo hoge existsが実行されるのである.
より複雑な条件による条件分岐を表現するには,if,elif,elseをネストする方法と&&,||を使用した条件部による方法がある.前者はソースが冗長になるので,&&や||を使用した方が見やすいコードになる場合がある(絶対ではない).
if mount /cdrom &>/dev/null && mount /floppy &>/dev/null then echo A else echo B fiこの場合,/cdromと/floppyの両方へのmountが成功した場合にecho Aが実行される.
if mount /cdrom &>/dev/null || mount /floppy &>/dev/null then echo A else echo B fiこの場合,/cdromか/floppyどちらかにmountできればecho Aが実行される.
if mount /cdrom &>/dev/null || mount /cdr &>/dev/null && mount /floppy &>/dev/null then echo A else echo B fiこの場合,まず/cdromへのmountを試みる.これに失敗すると/cdrへのmountを試みる./cdromか/cdrどちらかへのmountに成功した場合は,/floppyへのmountを試みる.そして/floppyへのmountに成功すれば,echo Aが実行される.つまり,/cdromか/cdrのどちらかへのmountに成功し,かつ/floppyへのmountが成功した場合に,echo Aが実行される.

