このページではシェルスクリプトでのifの使い方についてご紹介した。
プログラミング経験者であれば、ifが条件分岐に使うことはご存知だと思うが、シェルスクリプトの書き方は少し特殊だ。確認をしてみていただきたい。
目次
簡単に、ifとは?
プログラミングの制御文における「条件分岐」にあたる。文章的にすると「もしこの条件にあてはまるなら、この処理をしてほしい」となる。つまり特定の「条件のもと」に「分岐」するのである。また条件に合致しない場合は処理がおこなわれない。
例えば、次のようになる。
if(年齢が20以上であれば) //ifはもし○○であれば
あなたは成人です
else //そうでない場合には
あなたは未成年です
fi
というような形だ。
多くの場合条件式には条件判定専用の「test」コマンドを使用することになる。
しかし、基本的には意識しない。testコマンドを書かなくとも、「[ 条件式 ]」という記述で済んでしまう。
分岐をおこなう制御文にはほかにも「case」も存在する。ほかのページで記述するがこれは、ifよりも単純な分岐である。今回はifについて記述する。
シェルスクリプトのif
ifの文法基本
ifの書式は次の様になる。
1 2 3 |
if [ 条件1 ]; then 処理1 fi |
となる。もし「条件1」に当てはまれば、「処理1」を実行するという意味だ。
条件1に当てはまらない場合には処理2を実行したいとき、次の様にする。
1 2 3 4 5 |
if [ 条件1 ]; then 処理1 else 処理2 fi |
もし「条件1」に当てはまるなら、「処理1」を実行する。それ以外は「処理2」を実行するという意味だ。
さらに分岐を分けたいときにはelifを使う。「else if」の省略だ。
1 2 3 4 5 6 7 |
if [ 条件1 ]; then 処理1 elif [ 条件2 ]; then 処理2 else 処理3 fi |
もし「条件1」に当てはまるなら、「処理1」を実行する。それ以外で「条件2」に当てはまるなら「処理2」を実行する。それ以外は「処理3」を実行するという意味だ。
全体的に、スペースの位置とセミコロンに気をつけよう。
条件式を判定するtestコマンドについて
条件式を判定するための専用コマンドである。単体のコマンドとして存在している。Unix Like Systemであればほぼ確実にインストールされているコマンドだ。
下記ページで「演算子」について触れたがこれはtestコマンドのなかで多用されているものを列挙したのである。このコマンドは条件式を評価0ならば真、0以外ならば偽となる。
詳しい条件式は下記ページを参照していただきたい。
基本的にプログラムは真と判定されるとその処理が実行される。通常のプログラム言語の場合多くは0が偽、1以上が真となることが多いがtestコマンドはそうではないところに注意しよう。
基本的に「[ 条件式 ]」として記述されるので意識することは少ない。一応お伝えしておくと、
$ test 1 -eq 1 ; echo $?
とすると値がたしかめられる。
サンプルプログラムを確認
サンプルプログラムを確認して、どのように動くのか見てみてほしい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#!/usr/bin/bash #変数作成値代入 文字列などを代入した場合は0になる declare -i TEST_VAR declare -i TEST_VAR_NEST_EX TEST_VAR_NEST_EX=1 read -p: TEST_VAR #if文 #TEST_VARの値が0または1だった場合 真 if [ $TEST_VAR -eq 0 -o $TEST_VAR -eq 1 ]; then echo "TEST_VARの値は0もしくは1です" elif [ $TEST_VAR -eq 2 ]; then echo "TEST_VARの値は2です" elif [ $TEST_VAR -eq 3 ]; then : #何もしない else #if文のなかでif文が記述できる。 if [ $TEST_VAR_NEST_EX -eq 1 ]; then echo "TEST_VAR_NEST_EXは1です" fi fi |
出力結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$ ./if-ex1.sh :0 TEST_VARの値は0もしくは1です $ ./if-ex1.sh :1 TEST_VARの値は0もしくは1です $ ./if-ex1.sh :2 TEST_VARの値は2です $ ./if-ex1.sh :3 $ ./if-ex1.sh :4 TEST_VAR_NEST_EXは1です $ ./if-ex1.sh :5 TEST_VAR_NEST_EXは1です $ ./if-ex1.sh :aaa TEST_VARの値は0もしくは1です |
詳細解説
なんとなくイメージはできただろうか? これ以降、詳細をご説明していく。
なぜ「;」(セミコロン)がついているのか?「:」は何?
1 2 3 4 5 6 7 8 |
if [ 条件1 ] then 処理1 elif [ 条件2 ] then 処理2 else処理3 fi |
実際のところ上記の方法でも記述は許されている。
しかし「行」が増えてしまうため、可読性(コードの読みやすさ)に影響がでる。なので「;」をつけて一行にifとthenをまとめている。
「:」は書式上ifはなにかしらの処理が記述されてないと怒られてしまうので、無害なコードをはさむことによって、「なにもしない」状態をつくりだしている。
ちなみに「:」の終了コードは「0」つまり「真」となるので、後のページで紹介する「while」のループ条件に使うことがしばしある。
orやandやnot
スクリプトの例でさりげなく「or」を表わす「-o」を使用している。ほか「and」を表わす「-a」「not」を表わす「!」などがある。
orは「または」、andは「かつ」、notは「反転」とすると覚えやすいだろう。
今回の例だと「or」なのでTEST_VARが0と等しい「-o」ここで、もしくは TEST_VARは1と等しい場合、「真」となる。
ネスト(入れ子)について
基本的にプログラムはやスクリプトの制御文は「ネスト」入れ子が可能である。「ifのなかでifを記述する」できる。
ネストはいくらでも出来る。しかし例にあげているコードをみてもらえるとわかるが、可読性が下がる。
もしネストが多用されてしまうような状態ならば、一回条件式をみなおしてみよう。条件にだぶりがあることが多い。
ifは条件式の結果が0であれば実行される
じつはtestをつかわなくても、条件式の部分が0になればそれは「真」となり実行されるということも覚えておくと便利だ。
vi if-ex2.sh
1 2 3 4 |
#!/usr/bin/bash if ls / ; then echo "lsは成功しました" fi |
出力結果
$ ./if-ex2.sh
1 2 |
bin boot dev etc home initrd lib lib64 lost+found media mnt opt proc root run sbin selinux srv sys tmp usr var lsは成功しました |
まとめ
if文の使い方は一通りわかっただろうか?
ifはシェルスクリプトを使っていく上で、必ず必要になる。使い方がわかっていないとシェルスクリプトを書く意味がほとんどないと言っていい。
ぜひマスターしていただければと思う。
コメント