このページでは、シェルスクリプトの基本で 学習した内容を踏まえて、制御文を学習し、 より複雑な処理ができるようになりましょう。制御文とは難しい言葉に 感じるかも知れませんが、
というような、特定の条件に合致するか判定し、 その結果異なる処理を行う場合に、制御文が利用されます。 順を追って練習してみましょう。
まず引数(ひきすう)という概念を理解してもらいます。 「emacs」で「test2-1.sh」というファイルを作成しますが、 コマンドラインで下記のように入力してください。
emacsというエディタが立ち上がりますので、下記の内容を書いてください。 emacsの基本的な使い方は 大見先生のページに示されていますので参照してください。 保存ができたら、emacsを終了してください。
#!/bin/bash echo $@ echo $# echo $0 echo $1
まだどのような内容か理解していないと思いますが、下記のようにchmodを 使用して、実行可能な形式にします。
bash-2.05$ chmod +x test2-1.sh bash-2.05$ ls -l test2-1.sh -rwxr----- 1 susaki teacher 38 5月 7 23:56 test2-1.sh
「ls -l」の結果、実行可能な形式を示す「x」が表示されているか確認して 下さい。
実行するときは、
のように、皆さんの環境設定では./を つけないと実行されないようになっていますので注意してください。 それでは下記のように実行してみましょう。赤い文字の部分を入力して Enterキーを押してください。
例1) bash-2.05$ ./test2-1.sh 0 ./test2-1.sh 例2) bash-2.05$ ./test2-1.sh aaa bbbbb cc d e aaa bbbbb cc d e 5 ./test2-1.sh aaa
例1)では、./test2-1.shと打ち込んだだけです。 一方、例2)では、./test2-1.sh aaa bbbbb cc d eと、空白を区切りにして様々な文字列を入力しました。
ここで、「test2-1.sh」のスクリプトの中身を説明します。「test2-1.sh」の中で echoコマンドで表示させていたのは、下記のようなものです。
変数 | 意味 |
---|---|
$@ | 全引数(空白区切り) |
$# | 引数の数 |
$0 | コマンド名 |
$1 | 1番目の引数 |
引数とは、上記の例1、2では「./ test2-1.sh」より後に入力した文字列のことです。例1では、何も入力しなかった ので、全引数は空白行で表され、引数の数も0となりました。$0はコマンドその ものを表示しますので、「./test2-1.sh」が表示されました。
一方、例2では、引数を「aaa」「bbbbb」「cc」「d」「e」と5つ指定しました。 全引数として「aaa bbbbb cc d e」が表示され、引数の数は5、コマンド名は 「./test2-1.sh」、1番目の引数として「aaa」が表示されたわけです。
まずは、「test2-2.sh」というファイル名で、下記の内容を保存しましょう。
#!/bin/bash hour=`date +%H` if [ "$hour" -lt 12 ] then echo "今は午前です" else echo "今は午後です" fi
この中身を説明しますと、
#!/bin/bash hour=`date +%H` <- 現在の時刻を変数hourに代入 if [ "$hour" -lt 12 ] <- 変数hourが12より小さいか比較 then echo "今は午前です" <- 変数hourが12より小さければ実行 else echo "今は午後です" <- 変数hourが12より小さくなければ実行 fi
つまり、変数hourと12を比較して、12より小さければ"今は午前です"という メッセージを、そうでなければ"今は午後です"というメッセージを表示させる、 という内容です。
注意:変数を[ ]の判定式で使用する際には、 " "でくくる必要があるので注意せよ。(変数の中身が空の場合、 " "でくくっていないと、比較演算ができないというエラーが表示 されるため)
上記の例では、-ltという記号を使いました。 これは「左側の数字が右側の数字より小さければ真」という比較を行う 演算子です。比較を行う場合、文字列と数字とで使用する記号が異なりますので、 注意しましょう。
文字列 | |
---|---|
= | 等しい |
!= | 等しくない |
数字 | |
-eq | 等し�[ (equal to) |
-ne | 等しくな�[ (not equal to) |
-gt | より大き�[ (greater than) |
-ge | 以上 (greater than and equal to) |
-lt | より小さ�[ (less than) |
-le | 以�[ (less than and equal to) |
#!/bin/bash echo "好きな整数を入れてください" read num if [ "$num" -lt 100 ] then echo "$numは100未満です" elif [ "$num" -lt 1000 ] then echo "$numは100以上1000未満です" else echo "$numは1000以上です" fi
(実行結果) bash-2.05$ ./test2-2-1.sh 好きな整数を入れてください -9 -9は100未満です bash-2.05$ ./test2-2-1.sh 好きな整数を入れてください 120 120は100以上1000未満です bash-2.05$ ./test2-2-1.sh 好きな整数を入れてください 1000 1000は1000以上です
#!/bin/bash echo "3回目の小テストの点数(0から20までの数字)を入れてください" read num if [ "$num" -ge 0 -a "$num" -lt 7 ] then echo "もっと勉強しましょう。" elif [ "$num" -ge 7 -a "$num" -lt 15 ] then echo "まずまずです。" elif [ "$num" -ge 15 -a "$num" -le 20 ] then echo "よく頑張りました" else echo "入力した数字は0から20までの数字ではありません" fi
(実行結果) bash-2.05$ ./test2-2-2.sh 3回目の小テストの点数(0から20までの数字)を入れてください 0 もっと勉強しましょう。 bash-2.05$ ./test2-2-2.sh 3回目の小テストの点数(0から20までの数字)を入れてください 4 もっと勉強しましょう。 bash-2.05$ ./test2-2-2.sh 3回目の小テストの点数(0から20までの数字)を入れてください 19 よく頑張りました bash-2.05$ ./test2-2-2.sh 3回目の小テストの点数(0から20までの数字)を入れてください 21 入力した数字は0から20までの数字ではありません
#!/bin/bash echo "リテラシーの先生の名前をローマ字で入力してください" read name if [ "$name" = "suzuki" -o "$name" = "doi" ] then echo "あなたはAクラスの学生です" elif [ "$name" = "susaki" -o "$name" = "ohshiro" -o "$name" = "oshiro" ] then echo "あなたはBクラスの学生です" elif [ "$name" = "yamaga" -o "$name" = "shinohara" ] then echo "あなたはCクラスの学生です" else echo "入力ミスか、入力した名前の先生はいません。" fi
(実行結果) bash-2.05$ ./test2-2-3.sh リテラシーの先生の名前をローマ字で入力してください oshiro あなたはBクラスの学生です bash-2.05$ ./test2-2-3.sh リテラシーの先生の名前をローマ字で入力してください ohshiro あなたはBクラスの学生です bash-2.05$ ./test2-2-3.sh リテラシーの先生の名前をローマ字で入力してください yamaga あなたはCクラスの学生です bash-2.05$ ./test2-2-3.sh リテラシーの先生の名前をローマ字で入力してください sato 入力ミスか、入力した名前の先生はいません。 bash-2.05$ ./test2-2-3.sh リテラシーの先生の名前をローマ字で入力してください doi あなたはAクラスの学生です
#!/bin/bash if [ "$1" = "" ] then echo "先生の名前を引数として入力してください。" elif [ "$1" = "suzuki" -o "$1" = "doi" ] then echo "あなたはAクラスの学生です" elif [ "$1" = "susaki" -o "$1" = "ohshiro" -o "$1" = "oshiro" ] then echo "あなたはBクラスの学生です" elif [ "$1" = "yamaga" -o "$1" = "shinohara" ] then echo "あなたはCクラスの学生です" else echo "入力ミスか、入力した名前の先生はいません。" fi
(実行結果) bash-2.05$ ./test2-2-4.sh 先生の名前を引数として入力してください。 bash-2.05$ ./test2-2-4.sh ohshiro あなたはBクラスの学生です bash-2.05$ ./test2-2-4.sh suzuki あなたはAクラスの学生です bash-2.05$ ./test2-2-4.sh tanaka 入力ミスか、入力した名前の先生はいません。
ここではwhileを使った繰り返しについて学習します。このページの冒頭で 説明した引数を利用した処理を 紹介します。前回と同様、 「emacs」で「test2-3.sh」というファイルを作成します。下記の内容を 記述してください。
#!/bin/bash while [ "$1" != "" ] do echo $1 shift done
保存したら、chmodを使用して「test2-3.sh」を 実行形式に変更し、下記の赤字で表示されているように入力して 実行してみましょう。
bash-2.05$ ./test2-3.sh aaa bbbbb cc d e aaa bbbbb cc d e
スクリプトの中身を見ると、
#!/bin/bash while [ "$1" != "" ] <- $1(1番目の引数)が空白でない間、 do 処理を繰り返す echo $1 <- $1の表示 shift <- 引数のシフト($2が$1へ代入される) done
ということで、すべての引数が表示されることになります。
つまり、while文では、
while [ 条件式 ] do 処理 done
という形式を取り、条件式が満たされる間、doとdoneで囲まれた処理を繰り返し ます。
#!/bin/bash num=3 while [ "$num" -lt 10 ] do echo '$num'"の値は$num" num=`expr $num + 1` done
(実行結果) bash-2.05$ ./test2-3-1.sh $numの値は3 $numの値は4 $numの値は5 $numの値は6 $numの値は7 $numの値は8 $numの値は9
#!/bin/bash num=$1 while [ "$num" -lt 10 ] do echo '$num'"の値は$num" num=`expr $num + 1` done
(実行結果) bash-2.05$ ./test2-3-2.sh 2 $numの値は2 $numの値は3 $numの値は4 $numの値は5 $numの値は6 $numの値は7 $numの値は8 $numの値は9 bash-2.05$ ./test2-3-2.sh 8 $numの値は8 $numの値は9 bash-2.05$ ./test2-3-2.sh 12 bash-2.05$
#!/bin/bash num=$RANDOM echo "***** ある隠された値を当ててくださ�[ *****" while true do echo "0から32767までの数字を入力してください" read x if [ $x -gt $num ] then echo "もっと小さいですよ" elif [ $x -lt $num ] then echo "もっと大きいですよ" else echo "ずばり当たりです!" break fi done
(実行結果) bash-2.05$ ./test2-3-3.sh ***** ある隠された値を当ててくださ�[ ***** 0から32767までの数字を入力してください 10000 もっと大きいですよ 0から32767までの数字を入力してください 20000 もっと大きいですよ 0から32767までの数字を入力してください 30000 もっと小さいですよ (省略) 0から32767までの数字を入力してください 23500 もっと小さいですよ 0から32767までの数字を入力してください 23300 もっと大きいですよ 0から32767までの数字を入力してください 23490 もっと大きいですよ 0から32767までの数字を入力してください 23495 もっと大きいですよ 0から32767までの数字を入力してください 23498 ずばり当たりです!