■break、continue、return、exit
せ> type break
break is a shell builtin
せ> type continue
continue is a shell builtin
せ> type return
return is a shell builtin
■bashにgotoやjumpのようなコマンドはない
せ> type goto
-bash: type: goto: not found
せ> type jump
-bash: type: jump: not found
■continue文はfor、while、またはuntilループで次の繰り返しに飛ぶコマンド。
・ifブロックやcaseブロックから途中で抜けるコマンドはない。
・ラベル付きcontinue文はない。
※代わりに深さの数値を引数を指定できる
■break文はfor、while、またはuntilループを途中で抜けるコマンド。
・ifブロックやcaseブロックから途中で抜けるコマンドはない。
・ラベル付きbreak文はない。
※代わりに深さの数値を引数を指定できる
※javaではbreak文でswitch文を抜けるがbashでcaseブロックから抜ける場合は「;;」文
※プログラミング言語によってcontinue、break、return、exitで条件分岐ブロック、ループから抜けたり、call元に戻る文法が異なる。
※プログラミング言語によってgotoやjumpがあったりなかったりする
【課題】
プログラミング言語ごとに、ループ、条件分岐、配列、関数(メソッド)、論理式、ブロック抜け、関数から戻り、宣言、変数定義などの文法がそれぞれ異なるので、これらの文法項目ごとに、各言語ごとの構文を一覧表にまとめる。(とくに留意事項を含める)
■ifブロックから抜けれる?
せ> cat if.sh
#!/bin/bash
read X
if [ $X -gt 0 ] 2> /dev/null;then
echo X is larger than 0
elif [ $X -eq 0 ] 2> /dev/null;then
echo X is 0
elif [ $X -lt 0 ] 2> /dev/null;then
echo X is less than 0
else
echo X is not integer
fi
echo おわり
せ> bash ./if.sh
1
X is larger than 0
おわり
せ> bash ./if.sh
0
X is 0
おわり
せ> bash ./if.sh
-9223372036854775808 ←2の63乗
X is less than 0
おわり
せ> bash ./if.sh
-9223372036854775809
X is not integer
おわり
せ> bash ./if.sh
うんこ
X is not integer
おわり
【検証1】 if文の途中でbreak文
せ> cat if_break.sh
#!/bin/bash
read X
if [ $X -gt 0 ] 2> /dev/null;then
echo X is larger than 0
elif [ $X -eq 0 ] 2> /dev/null;then
echo X is 0
# insert break
break
elif [ $X -lt 0 ] 2> /dev/null;then
echo X is less than 0
else
echo X is not integer
fi
echo おわり
せ> bash ./if_break.sh
0
X is 0
./if_break.sh: line 8: break: only meaningful in a `for', `while', or `until' loop
おわり
せ> bash ./if_break.sh
うんこ
X is not integer
おわり
【検証2】 if文の途中でcontinue文
せ> cat if_continue.sh
#!/bin/bash
read X
if [ $X -gt 0 ] 2> /dev/null;then
echo X is larger than 0
elif [ $X -eq 0 ] 2> /dev/null;then
echo X is 0
# insert continue
continue
elif [ $X -lt 0 ] 2> /dev/null;then
echo X is less than 0
else
echo X is not integer
fi
echo おわり
せ> bash ./if_continue.sh
1
X is larger than 0
おわり
せ> bash ./if_continue.sh
0
X is 0
./if_continue.sh: line 8: continue: only meaningful in a `for', `while', or `until' loop
おわり
せ> bash ./if_continue.sh
うんこ
X is not integer
おわり
※ループ内じゃないところでbreakやcontinueを使えない
せ> type goto
-bash: type: goto: not found
※「goto」というコマンド、bashシンボルはない。
※if文やcase文の途中から抜ける方法はない?
■continue文
【検証3】 for文とcontinue文
せ> for ((i=1;i<=4;i++));do echo $iループ目;echo ち;[ $i -eq 2 ] && continue;echo んこ;done
1ループ目
ち
んこ
2ループ目
ち ←このループ回の途中で次のループに飛んでる
3ループ目
ち
んこ
4ループ目
ち
んこ
せ> echo $?
0
【検証4】 while文とcontinue文
せ> i=0;while ((i<=4));do ((i++));echo $iループ目;echo ち;
[ $i -eq 2 ] && continue;echo んこ;done
1ループ目
ち
んこ
2ループ目
ち ←このループ回の途中で次のループに飛んでる
3ループ目
ち
んこ
4ループ目
ち
んこ
5ループ目
ち
んこ
せ> echo $?
0
【検証5】2重ループの内側のループでcontinue文
せ> cat double_loop.sh
#!/bin/bash
for((i=1;i<=3;i++))
do
for((j=1;j<=3;j++))
do
echo iは$iでjは$j
[ $i -eq 2 ] && continue
echo あばばばば
done
done
せ> bash ./double_loop.sh
iは1でjは1
あばばばば
iは1でjは2
あばばばば
iは1でjは3
あばばばば
iは2でjは1 ←i=2の時だけ「あばばばば」が無い
iは2でjは2 ←i=2の時だけ「あばばばば」が無い
iは2でjは3 ←i=2の時だけ「あばばばば」が無い
iは3でjは1 ←i=2の時だけ「あばばばば」が無い
あばばばば
iは3でjは2
あばばばば
iは3でjは3
あばばばば
せ> echo $?
0
【検証6】2重ループの内側のループでcontinue文 その2
せ> cat double_loop2.sh
#!/bin/bash
for((i=1;i<=3;i++))
do
for((j=1;j<=3;j++))
do
echo iは$iでjは$j
[ $j -eq 2 ] && continue
echo あばばばば
done
done
せ> bash ./double_loop2.sh
iは1でjは1
あばばばば
iは1でjは2 ←j=2の時だけ「あばばばば」が無い
iは1でjは3
あばばばば
iは2でjは1
あばばばば
iは2でjは2 ←j=2の時だけ「あばばばば」が無い
iは2でjは3
あばばばば
iは3でjは1
あばばばば
iは3でjは2 ←j=2の時だけ「あばばばば」が無い
iは3でjは3
あばばばば
せ> echo $?
0
■break文
【検証7】 for文とbreak文
せ> for ((i=1;i<=4;i++));do echo $iループ目;echo ち;[ $i -eq 2 ] && break;echo んこ;done
1ループ目
ち
んこ
2ループ目
ち
せ> echo $?
0
【検証8】 while文とbreak文
せ> i=0;while ((i<=4));do ((i++));echo $iループ目;echo ち;
[ $i -eq 2 ] && break;echo んこ;done
1ループ目
ち
んこ
2ループ目
ち
せ> echo $?
0
【検証9】2重ループの内側のループでbreak文
せ> cat double_loop3.sh
#!/bin/bash
for((i=1;i<=3;i++))
do
for((j=1;j<=3;j++))
do
echo iは$iでjは$j
[ $i -eq 2 ] && break
echo あばばばば
done
done
せ> bash double_loop3.sh
iは1でjは1
あばばばば
iは1でjは2
あばばばば
iは1でjは3
あばばばば
iは2でjは1 ←i=2のbreakのところで内側のループから抜けた
iは3でjは1
あばばばば
iは3でjは2
あばばばば
iは3でjは3
あばばばば
せ> echo $?
0
【検証10】2重ループの内側のループでbreak文 ―その2―
せ> cat double_loop4.sh
#!/bin/bash
for((i=1;i<=3;i++))
do
for((j=1;j<=3;j++))
do
echo iは$iでjは$j
[ $j -eq 2 ] && break
echo あばばばば
done
done
せ> bash ./double_loop4.sh
iは1でjは1
あばばばば
iは1でjは2 ←j=2のbreakのところで内側のループから抜けた
iは2でjは1
あばばばば
iは2でjは2 ←j=2のbreakのところで内側のループから抜けた
iは3でjは1
あばばばば
iは3でjは2 ←j=2のbreakのところで内側のループから抜けた
せ> echo $?
0
【検証11】2重ループの内側のループでbreak文 ―その3―
せ> cat double_loop5.sh
#!/bin/bash
for((i=1;i<=3;i++))
do
for((j=1;j<=3;j++))
do
[ $j -eq 2 ] && break
echo iは$iでjは$j
echo あばばばば
done
done
せ> bash ./double_loop5.sh
iは1でjは1
あばばばば
iは2でjは1
あばばばば
iは3でjは1
あばばばば ←j=2のbreakのところで内側のループから抜けた
せ> echo $?
0
■continue "深さ"
【検証12】 continue 2
せ> cat double_loop6.sh
#!/bin/bash
for((i=1;i<=3;i++))
do
for((j=1;j<=3;j++))
do
echo iは$iでjは$j
[ $i -eq 2 ] && continue 2
echo あばばばば
done
done
せ> bash ./double_loop6.sh
iは1でjは1
あばばばば
iは1でjは2
あばばばば
iは1でjは3
あばばばば
iは2でjは1 ←【検証5】と比較。【検証9】の結果と同じになった。つまり「continue 2」実行後内側のループから抜け出た
iは3でjは1
あばばばば
iは3でjは2
あばばばば
iは3でjは3
あばばばば
せ> echo $?
0
■break "深さ"
【検証13】 break 2
せ> cat double_loop7.sh
#!/bin/bash
for((i=1;i<=3;i++))
do
for((j=1;j<=3;j++))
do
echo iは$iでjは$j
[ $i -eq 2 ] && break 2
echo あばばばば
done
done
せ> bash ./double_loop7.sh
iは1でjは1
あばばばば
iは1でjは2
あばばばば
iは1でjは3
あばばばば
iは2でjは1 ←【検証9】と比較。「break 2」実行後、内側と外側のループを一気に抜け出た
せ> echo $?
0
■exit文
【検証14】 スクリプトで実行
せ> type exit
exit is a shell builtin
せ> cat exit.sh
#!/bin/bash
read X;[[ $X -gt 0 ]] && exit 1 || [[ $X -eq 0 ]] && exit 2 || [[ $X -lt 0 ]] && exit 3 ←①
せ> bash ./exit.sh
1
せ> echo $?
1
せ> bash ./exit.sh
0
せ> echo $?
2
せ> bash ./exit.sh
-2
せ> echo $?
3
せ> bash ./exit.sh
hoge
せ> echo $?
2 ←変数「hoge」はnullなので値は0と評価された
※①をカレントシェルからワンライナーで実行するとカレントシェルセッションが終了する
【検証15】 関数で実行
せ> bash
せ> function exit_func { ←②
> read X;[[ $X -gt 0 ]] && exit 1 || [[ $X -eq 0 ]] && exit 2 || [[ $X -lt 0 ]] && exit 3
> }
せ> exit_func
1
exit
せ> echo $?
1
せ> bash
せ> function exit_func {
> read X;[[ $X -gt 0 ]] && exit 1 || [[ $X -eq 0 ]] && exit 2 || [[ $X -lt 0 ]] && exit 3
> }
せ> exit_func
0
exit
せ> echo $?
2
せ> bash
せ> function exit_func {
> read X;[[ $X -gt 0 ]] && exit 1 || [[ $X -eq 0 ]] && exit 2 || [[ $X -lt 0 ]] && exit 3
> }
せ> exit_func
-3
exit
せ> echo $?
3
※②をカレントシェルからワンライナーで実行するとカレントシェルセッションが終了する
■retruen文
【検証16】 スクリプトの中のretruen文
せ> cat return.sh ←③
#!/bin/bash
read X;[[ $X -gt 0 ]] && return 1 || [[ $X -eq 0 ]] && return 2 || [[ $X -lt 0 ]] && return 3
せ> bash return.sh
5
return.sh: line 2: return: can only `return' from a function or sourced script
せ> source return.sh
1
せ> echo $?
1
せ> source return.sh
0
せ> echo $?
2
せ> source return.sh
-800
せ> echo $?
3
※③をbashコマンドによりサブシェルで実行するとエラーになる
※③をsourceコマンドによりカレントシェルで実行できる
【検証17】 関数の中のreturn文
関数の最後には return コマンドを指定し、その引数として与えた値が関数の終了ステータスとなる。
return コマンドの引数に指定できる値は、0 もしくは 1~255 の正の整数値のみである。マイナスの値も指定可能であるが、-1 を指定した場合は結果的に 255 になる。
この return コマンドは省略可能で、省略された場合は関数内で最後に実行されたコマンドの終了ステータスが、関数自体の終了ステータスとなる。
せ> function return_func { ←④
> read X;[[ $X -gt 0 ]] && return 1 || [[ $X -eq 0 ]] && return 2 || [[ $X -lt 0 ]] && return 3
> }
せ> return_func
100
せ> echo $?
1
せ> function return_func {
> read X;[[ $X -gt 0 ]] && return 1 || [[ $X -eq 0 ]] && return 2 || [[ $X -lt 0 ]] && return 3
> }
せ> return_func
0
せ> echo $?
2
せ> function return_func {
> read X;[[ $X -gt 0 ]] && return 1 || [[ $X -eq 0 ]] && return 2 || [[ $X -lt 0 ]] && return 3
> }
せ> return_func
-60
せ> echo $?
3
※④をカレントシェルからワンライナーで実行できる