for文による処理の繰り返し
次は、繰り返し処理を記述してみましょう。ここでは例として、次のようなシェルスクリプトを作成します。作成できたら実行権限を付与してください。
#!/bin/bash for i in 1 2 3 4 5 do touch "sample${i}.txt" done
実行してから、ls
コマンドを実行してみましょう。
# ./sample4.sh # ls sample*.txt sample1.txt sample2.txt sample3.txt sample4.txt sample5.txt
5つのファイルが出来上がっています。この結果から分かるように、このシェルスクリプトはtouch
コマンドを5回実行するという繰り返し処理を行っています。
繰り返し処理にはfor
文を使っています。for
文ではまずfor~
の行で次の2つを指定します。
-
繰り返し処理で使用する「変数」(sample4.shでは
i
) -
変数に代入する「値のリスト」(sample4.shでは
1 2 3 4 5
の5つ)
そして、do
からdone
の間に、繰り返し実行したい処理を記述します。
for
文の実行中のようすは次図のとおりです。
「値のリスト」から値を1つ取り出し、「変数」に代入します(①)。それから繰り返し処理に入り一度実行します(②)。繰り返し処理の実行が一度終わると、「値のリスト」の次の値を1つ取り出して、「変数」に代入します(③)。そして、繰り返し処理を一度実行します(④)。これを「値のリスト」の全ての値について行います(⑤)。
こうしてtouch
コマンドが5回実行され、sample1.txt、sample2.txt、……、sample5.txtという5つのファイルが作成されました。
seqコマンドについて
先ほどのサンプルのように「1から5」を指定するときに1 2 3 4 5
とスペース区切りで値を指定しました。しかし、これが「1から100まで」となってくると記述が大変面倒です。
そんなときに便利なのがseq
コマンドです。seqはsequence(シークエンス)の先頭3文字で、連続した値を生成するときに便利です。
例えば、次のコマンドを実行すると、1から10までが表示されます。
# seq 10
また、次のようにすると10から50までが表示されます。
# seq 10 50
さらに、次のようにすると10から50までを5区切りで表示します。
# seq 10 5 50
これを利用して先ほどのサンプルを以下のように書き換えてみましょう。
#!/bin/bash for i in `seq 10 5 50` do touch "sample${i}.txt" done
コマンドを`
(バッククォーテーション)で括ると、その実行結果を取得できます。そのため、seq 10 5 50
の部分は「10、15、……、50」のリストになります。
実行後、ls
コマンドで見てみると、sample10.txt、sample15.txt、……、sample50.txtというファイル生成されています。
while文による処理の繰り返し
繰り返し処理を行う代表的な文としてもう1つ、while
文があります。for
文での繰り返し回数は、値のリストに含まれる要素の数によりました。一方、while
文は繰り返し回数を指定するのではなく、繰り返しを継続する条件を指定します。この条件を満たしている間は、処理を繰り返し実行します。
次のサンプルを見てください。do
~done
の中に繰り返し処理を記述しているのはfor
文と同じです。
#!/bin/bash VAL=0 while [ ${VAL} -ne 10 ] do VAL=`expr ${VAL} + 1` echo ${VAL} done
実行結果は次のようになります。
1 2 3 4 5 6 7 8 9 10
動作のようすは次図のとおりです。
3行目のwhile
に続く[ ${VAL} -ne 10 ]
が、繰り返しを継続する条件です。条件の指定の仕方はif
文と同じで、意味は「変数VAL
が10ではない」です。
5行目のVAL=`expr ${VAL} + 1`
は、変数VAL
に1追加した値をVAL
に代入するという処理です。つまり、VAL
の値は繰り返し処理のたびに1ずつ追加されていきます。そうして繰り返しを継続する条件(VAL
の値が10ではない)を満たさなくなった時点で、繰り返し処理は終了します。
6行目のecho ${VAL}
ではVAL
の値を表示しています。そのため、繰り返し処理のたびに1、2、……、10と表示されていきました。
readコマンドによる標準入力の取得
read
コマンドを使うと、ユーザーが入力した値をシェルスクリプトで読み取ることができます。サンプルで動作を確認してみましょう。
#!/bin/bash echo "数値を入力してください:" read VAL VAL2=`expr ${VAL} + ${VAL}`; echo "入力した値は${VAL}です。${VAL}の2倍の値は${VAL2}です。"
これを実行すると、入力待ちの状態になります。数値を入力し[Enter]キーを押下すると、次のように表示されます。
# ./sample6.sh 数値を入力してください: 10 入力した値は10です。10の2倍の値は20です。
read
コマンドは指定した変数(今回はVAL
)に入力された値を代入します。sample6.shでは3行目でそれを足し合わせ、2倍の数値を作って、4行目のecho
コマンドで表示しています。
このシェルスクリプトに、while文とif文と組み合わせてみましょう。次のスクリプトは、「-1」を入力したときに処理が終了し、それ以外の値を入力したときには処理を繰り返します。
#!/bin/bash VAL=0 while [ ${VAL} -ne -1 ] do echo "数値を入力してください:" read VAL VAL2=`expr ${VAL} + ${VAL}`; if [ ${VAL} -eq -1 ] then echo "終了します。" else echo "入力した値は${VAL}です。${VAL}の2倍の値は${VAL2}です。" fi done
# ./sample7.sh 数値を入力してください: 1 入力した値は1です。1の2倍の値は2です。 数値を入力してください: 3 入力した値は3です。3の2倍の値は6です。 数値を入力してください: 9 入力した値は9です。9の2倍の値は18です。 数値を入力してください: -1 終了します。