シェルスクリプトに挑戦しよう(15)繰り返し処理の中断“応用力”をつけるためのLinux再入門(35)

今回は、繰り返し処理を中断する際に使用する「break」と「continue」を解説します。

» 2019年01月30日 05時00分 公開
[西村めぐみ@IT]
「“応用力”をつけるためのLinux再入門」のインデックス

“応用力”をつけるためのLinux再入門

繰り返しの処理を中断するには?

 「for」や「while」のdo〜doneの中で処理を中断したい場合は、「break」または「continue」を使用します。

 breakの場合、“繰り返し処理全体”を終了します。例えば、while文の中に書かれていた場合、whileのブロック全体を終了して、doneの後ろの処理に進みます。

 対して、continueは“繰り返し内の処理”を中断します。繰り返し処理そのものは続行されるので、繰り返しの最初、つまりwhileの行に戻ります。

●中断(1)breakで繰り返し全体を終了する

 繰り返し処理そのものを終わらせたい場合は、breakを使用します。

 次のスクリプトでは、readコマンドでキーボードからの入力を読み込み(スクリプト内(1))、case文で読み込んだ内容によって処理を分岐させています。

#! /bin/bash
echo -n "Say hello? [y/n] "	#最初にメッセージを表示する
while read s; do		#標準入力を受け取って変数sにセット(1)
  case "$s" in			#変数sで分岐
    "y") echo "Hello!";;	#「y」の場合、Hello!とあいさつ(2)
    "n") echo "ok"; break;;	#「n」ならwhile文を終了(3)
    *) echo "input [y] or [n]";;	#それ以外の場合はメッセージを表示(4)
  esac
  echo -n "Again? [y/n] "	#メッセージを表示してwhileに戻る(5)
done
echo "bye!"			#最後にメッセージを表示(6)
▲「y」でHello!とあいさつする(sayhello)

 入力した文字が「y」なら、echoコマンドで「Hello!」と表示します(同(2))。「n」ならば「ok」と表示後、breakで処理を中断します(同(3))。それ以外の文字が入力された場合には、「input [y] or [n]」と表示して処理を続行します(同(4))。

 なお、入力前のメッセージ、つまりreadコマンドの直前に実行されるechoコマンドでは、メッセージ表示後に改行しないように「-n」オプションを付けています。

$ chmod +x sayhello
$ ./sayhello
Say hello? [y/n] y[Enter]	← 最初のメッセージの後、(1)のreadで入力待ちしているので「y」と入力して[Enter]
Hello!
again? [y/n] aaa[Enter]	← case文が終了して、(5)が表示されて(1)に戻って入力待ちしているので「aaa」と入力して[Enter]
input [y] or [n]	← 「y」でも「n」でもないので(3)のメッセージが表示された
again? [y/n] n[Enter]	← case文が終了して(5)が表示、(1)のreadに対し「n」と入力して[Enter]
ok	← (3)のメッセージを表示してwhile文を終了
bye!	← (6)のメッセージが表示された
▲実行結果(sayhello)

 このスクリプトでは、キーボードで[n]を入力したときにbreakで終了しています。

 [CTRL]+[D]でreadコマンドに対して入力を終了させた場合、そして[CTRL]+[C]でスクリプトを中断した場合と比較してみましょう。

$ ./sayhello
Say hello? [y/n] n	← (1)のreadに対し[n]を入力
ok	← (3)でokと表示してbreak
bye!	← (3)のbreakでwhileを抜けて(6)のメッセージが表示された
$
▲[n]で終了(breakで終了)した場合の実行例(sayhello)
$ ./sayhello
Say hello? [y/n] 	← (1)のreadに対し[CTRL]+[D]を入力
bye!	← readできなかったのでwhileを抜けて(6)のメッセージが表示された
$
▲[CTRL]+[D]で終了した場合の実行例(sayhello)
$ ./sayhello
Say hello? [y/n] ^C	← (1)のreadに対し[CTRL]+[C]を入力
$	← スクリプトが即座に終了したので(6)が実行されていない
▲[CTRL]+[C]で終了した場合の実行例(sayhello)

●中断(2)continueで繰り返し内の処理を中断する

 breakでは処理が中断されてwhile文全体が終了するのに対し、continueは処理を中断して繰り返しの先頭、つまりwhileの行に戻ります。

 先ほどの「sayhello」スクリプトで、[Enter]だけ入力した場合はメッセージを出さずに再度入力を待つようにしてみましょう。

 [Enter]だけ入力すると、入力内容が空になるので、case文では「"")」で分岐できます(スクリプト内(1))。

#! /bin/bash
echo -n "Say hello? [y/n] "
while read s; do
  case "$s" in
    "y") echo "Hello!";;
    "n") echo "ok"; break;;
    "") continue;;	← (1)入力が[Enter]のみの場合は何もせずにwhileに戻る
    *) echo "input [y] or [n]";;
  esac
  echo -n "again? [y/n] "
done
echo "bye!"
▲[Enter]のみの場合はcontinue(sayhelloを加工)

 このスクリプトを実行すると、次のようになります。[Enter]だけ入力すると、すぐwhileに戻ってreadで入力待ちしている様子が分かります。

$ ./sayhello 
Say hello? [y/n] 	← [Enter]のみ入力
		← whileの先頭に戻り再度readで入力待ちしているので[Enter]
y		← whileの先頭に戻り再度readで入力待ちしているのでyと入力して[Enter]
again? [y/n] n
ok
bye!
▲実行結果(sayhello)

for文とwhile文

 for文もwhile文も、「繰り返しの処理を行う」という点では共通です。for文と同じような繰り返しをwhile文で書くと次のようになります。

●引数を順番に処理する

 引数を順番に処理する場合は「shift」を使って、引数を1つずつ“ずらし”ます。例えば、引数が「aaa b cc」の場合、1回目のshiftを実行すると引数は「b cc」の2つ、2回目のshiftの後は引数が「cc」の1つになります。shiftを繰り返して引数の数が0になったら、条件がFALSEになり、while文が終了します。

#! /bin/bash
while [ $# -gt 0 ]; do	#引数の個数が0より大きい間繰り返す
    echo "$1"		#1つ目の引数を表示
    shift		#引数を1つずらす(シフトする)
done
▲引数を順番に表示する(whileargv)
$ chmod +x whileargv
$ ./whileargv aaa b cc
aaa
b
cc
▲実行結果(whileargv)

●回数を指定して実行する

 本連載第33回で取り上げた「for ((i=1; i<=10; i++)) do 〜 done」の処理をwhile文で書くと、以下のようになります。

#! /bin/bash
i=1			#変数iに「1」をセットする(1)
while [ $i -le 10 ]	#変数iが「10以下」の間繰り返す(2)
do
    echo "$i"	#変数iを表示する
    ((i++))	#変数iを1増やす(3)
done
▲whileで回数を指定して繰り返す(whilecount)

 このスクリプトでは、whileの前に「i=1」を実行して((1))、whileの条件として「[ $i -le 10 ]」を指定します((2))。「-le」は“lesser or equal”、つまり“以下”という意味です。

 続いて、「do 〜 done」の中では「((i++))」によって、変数iの値を増やします((3))。この「((i++))」が抜けてしまうと、iがずっと1のままとなり、while文を終了できなくなるので注意してください。スクリプトを終了できなくなった場合は、キーボードで[CTRL]+[C]を入力することで強制的に終了させることができます。

$ chmod +x whilecount
$ ./whilecount
1
2
3
4
5
6
7
8
9
10
▲実行結果(whilecount)

筆者紹介

西村 めぐみ(にしむら めぐみ)

もともとはDOSユーザーで「DOS版UNIX-like tools」を愛用。ソフトハウスに勤務し生産管理のパッケージソフトウェアの開発およびサポート業務を担当、その後ライターになる。著書に『図解でわかるLinux』『らぶらぶLinuxシリーズ』『Accessではじめるデータベース超入門[改訂2版]』『macOSコマンド入門』など。地方自治体の在宅就業支援事業にてMicrosoft Officeの教材作成およびeラーニング指導を担当。会社などの“PCヘルパー”やピンポイント研修なども行っている。


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。