シェルスクリプトに挑戦しよう(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文で読み込んだ内容によって処理を分岐させています。

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

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

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

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

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

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

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

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

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

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

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

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

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

  1. $ ./sayhello
  2. Say hello? [y/n] Enter]のみ入力
  3. whileの先頭に戻り再度readで入力待ちしているので[Enter
  4. y whileの先頭に戻り再度readで入力待ちしているのでyと入力して[Enter
  5. again? [y/n] n
  6. ok
  7. 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文が終了します。

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

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

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

  1. #! /bin/bash
  2. i=1 #変数iに「1」をセットする(1)
  3. while [ $i -le 10 ] #変数iが「10以下」の間繰り返す(2)
  4. do
  5. echo "$i" #変数iを表示する
  6. ((i++)) #変数iを1増やす(3)
  7. 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]を入力することで強制的に終了させることができます。

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

筆者紹介

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

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

Copyright © ITmedia, Inc. All Rights Reserved.

スポンサーからのお知らせPR

Linux �ス�ス�ス�ス OSS 鬮ォ�ェ陋滂ソス�ス�コ闕オ譁溷クキ�ケ譎「�ス�ウ驛「�ァ�ス�ュ驛「譎「�ス�ウ驛「�ァ�ス�ー

髫エ蟷「�ス�ャ髫エ魃会スス�・髫エ蟶キ�」�ッ闖ォ�」

注目のテーマ

4AI by @IT - AIを作り、動かし、守り、生かす
Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

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

メールマガジン登録

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