6. Bash(bourne-again shell)とフローチャート

bash(bourne-again shell)はUNIX系OSで使われるシェルです。

ここでは、具体的にbashとフローチャートの対応関係について書きます。ソースコードとフローチャートを順番に書くことで、ソースコードの処理の流れを明確にします。

6.1. 三項の条件演算子

bashでの三項の条件演算子は「条件付き実行」を使います。

条件付き実行の構文

$((条件?式1:式2))

条件 大小を比較する比較演算
式1 条件が真のときの計算される
式2 条件が偽のときの計算される

※式は算術演算でないといけない。

比較演算子「((...))内で使う比較演算子」

演算子 説明
== 等しい(=)
!= 等しくない(<>)
< より小さい(<)
<= 以下(<=)
> より大きい(>)
>= 以上(>=)

条件付き実行の例

bash_conditional_op.sh

#!/bin/sh

sum=10
num=$((sum >= 60 ? 100 : 0))
echo $num #「0」を表示

条件付き実行のフローチャート

_images/bash_conditional_op.gif

6.2. if...else文

if文は条件によって、処理を分岐したときに利用します。

if..elseの構文

if [ 条件式1 ]
then
    命令文1
elif [ 条件式2 ]
then
    命令文2
else
    命令文3
fi

※条件式:下記の比較演算子などを利用し真偽となる条件を記載する。命令文:実行したい処理を記載する。

条件式1 条件が真のとき命令文1を実行する条件式
命令文1 条件式1を満たす時に実行される
条件式2 条件が真のとき命令文2を実行する条件式。条件式1の条件を満たさないときに判定される
命令文2 条件式2を満たす時に実行される
else どの条件式も満たさないときに命令文3を実行する
命令文3 elseのときに実行される

比較演算子

演算子 説明 由来
-eq 等しい(=) EQual
-ne 等しくない(<>) Not Equal
-lt より小さい(<) Less Than
-le 以下(<=) Less than or Equal
-gt より大きい(>) Greater Than
-ge 以上(>=) Greater than or Equal

if..elseのフローチャート

_images/ifelse.gif

if..elseの例

bash_if_else.sh

比較演算子「-ge」への参照

#!/bin/sh

age=16
result=""
if [ $age -ge 70 ]
then
	result="心の欲する所に従って矩を踰えず"
elif [ $age -ge 60 ]
then
	result="耳順う"
elif [ $age -ge 50 ]
then
	result="天命を知る"
elif [ $age -ge 40 ]
then
	result="惑わず"
elif [ $age -ge 30 ]
then
	result="立つ"
elif [ $age -ge 15 ]
then
	result="学に志す"
else
	result="無し"
fi
echo $result #=> 学に志す

※「$age -ge 70」は「$age ≧ 70」のことです。


if..elseの例のフローチャート

_images/rongo.gif

6.3. switch文

switch文の構文

case 式 in
    値1)
        命令文1
        ;;
    値2)
        命令文2
        ;;
    *)
        命令文3
        ;;
esac

※ 式:値を返す式を記載する。 値:式の計算結果。

値1 式が値1を返したとき、命令文1を実行する
命令文1 式が値1のとき実行される。
値2 式が値2を返したとき、命令文1を実行する
命令文2 式が値2のとき実行される。
* 式が指定してない値(値1、値2以外)を返したとき、命令文3を実行する
命令文3 式が指定してない値のき実行される。


switch文のフローチャート
_images/switch.gif

switch文の例

bash_case.sh

#!/bin/sh

month=2
result=""
case $month in
  1)
    result="January"
    ;;
  2)
    result="February"
    ;;
  3)
    result="March"
    ;;
  4)
    result="April"
    ;;
  5)
    result="May"
    ;;
  6)
    result="June"
    ;;
  7)
    result="July"
    ;;
  8)
    result="August"
    ;;
  9)
    result="September"
    ;;
  10)
    result="October"
    ;;
  11)
    result="November"
    ;;
  12)
    result="December"
    ;;
  *)
    ;;
esac
echo $result   #Februaryを表示

switch文例のフローチャート

_images/switch_ex.gif

6.4. for文

for文の構文

for ((初期化式; 条件式; 再初期化式)) {
    命令文
}
   
初期化式 「i=0」など、forループ内で使われる変数などの初期化を行う。
条件式 ループ処理が継続する条件を「i < 10」などの条件式で書かれる
再初期化式 「i=i+1」などのように初期化式で設定された変数を再設定するのに使われる。

for文のフローチャート

_images/for.gif

1~10の合計を求めるfor文の例

bash_for.sh

#!/bin/sh

sum=0
for ((i=1; i <= 10; i++))
do
  ((sum += i))
done
echo $sum #=>55

※「i++」は「i = i + 1」のことを表します。

※「sum += i」は「sum = sum + i」のことを表します。


for文例のフローチャート

_images/for_ex.gif

6.5. for-each文

foreachのループ文の説明


for-each文の構文

for 変数 in 配列{
    命令文
}

foreach文は配列・コレクションの数だけ、変数に配列の要素を順番に格納しながら処理をを繰り返します。

1~10の合計を求める。for-each文の例


bash_for_each.sh
#!/bin/sh

nums="1 2 3 4 5 6 7 8 9 10"
sum=0
for num in $nums
do
  ((sum=sum+num))
done
echo $sum #55を表示

for-each文のフローチャート

_images/for_each.gif

6.6. while文

while文の構文

while [ 継続条件式 ] {
    命令文
}

while文のフローチャート

_images/while.gif

1~10の合計を求める。while文の例

bash_while.sh

#!/bin/sh

sum=0
i=1
while [ $i -le 10 ]
do
  ((sum=sum+i))
  ((i=i+1))
done
echo $sum #55を表示

while文例のフローチャート

_images/while_ex.gif

6.7. do..while文

bashにdo..while処理はありません。while文、if文、break文を使って類似の処理を記載します。

※:do..while文の一般的な例はJavaのdo..while文を参照してください。

do-while文の構文

while :
do
    命令文
    if ! [ 継続条件式 ]
    then
        break
    fi
done

do-while文のフローチャート

_images/do_while.gif

1~10の合計を求める。do-while文の例

bash_do_while.sh

#!/bin/sh

sum=0
i=1
while : #「:」で条件なしでループする。
do
  ((sum=sum+i))
  ((i=i+1))
  if ! [ $i -le 10 ]
  then
    break
  fi
done
echo $sum #55を表示

do-while文のフローチャート

_images/do_while_ex.gif

6.8. continue文

continueの構文

ループ制御文
do
    if [ 条件 ]
    then
        continue
    fi
    その後の処理
done

continue文はfor、whileのループ制御文の「その後の処理」をスキップさせ、ループ処理を継続させます。


continue構文のフローチャート

_images/continue.gif

continue文の例

bash_continue.sh

#!/bin/sh

sum=0
for ((i=1; i <= 10; i++))
do
  if [ $i -eq 3 ]
  then
    continue
  fi
  ((sum=sum+i))
done
echo $sum #52を表示

continue文のフローチャート

_images/bat_for_continue_ex.gif

6.9. break文

break文はループ制御文とswitch文を抜けだします。

breakの構文

ループ制御文
do
    if [ 条件 ]
    then
        break
    fi
    その後の処理
done

break文はfor、foreeach、whileのループ制御文を抜け出します。


break構文のフローチャート

_images/break.gif

break文の例

bash_break.sh

#!/bin/sh

sum=0
for ((i=1; i <= 10; i++))
do
  ((sum=sum+i))
  if [ $sum -ge 30 ]
  then
    break
  fi
done
echo $sum #36を表示

break文のフローチャート

_images/bat_for_break_ex.gif

6.10. ラベル付きcontinue文

bashではラベル付continue文はありません。代わりに、対象となるループ制御文を深さの数値で指定してその後の処理をスキップすることができます。

※参照:ラベル付きcontinue文はJavaにありますので参考にしてください

深さを指定するcontinueの構文

ループ制御文2
do
    ループ制御文1
    do
        if [ 条件 ]
        then
            continue 深さの数値
        fi
        その後の処理
    done
    その後の処理1
done

「深さの数値」を「2」とした場合for、foreach、whileの「ループ制御文1」の「その後の処理」、「ループ制御文2」の「その後の処理1」をスキップします。


continue文のフローチャート

_images/bash_label_continue.gif

これは主に多重ループを抜ける処理をスマートの書くために使います。

C言語ではこの機能がないため、goto文を使って記述することもあります。



深さを指定するcontinue文の例

bash_double_loop_continue.sh

#!/bin/sh

sum=0
for ((i=1; i <= 10; i++))#ループ 2
do
  for ((j=1; j <= 10; j++))#ループ 1
  do
    if [ $i -eq 3 ]
    then
      continue 2
    fi
    ((sum=sum+i*j))
  done
done
echo $sum #=>2860

ラベル付きcontinue文のフローチャート

_images/bash_double_loop_continue_exp.gif

6.11. ラベル付きbreak

bashではラベル付break文はありません。代わりに、同様のものとして対象となるループ制御文を深さの数値で指定してループ処理を抜ける構文があります。

※参照:ラベル付きbreak文はJavaにありますので参考にしてください

深さを指定するbreakの構文

ループ制御文 2
do
    ループ制御文 1
    do
        if [ 条件 ]
        then
            break 深さ数値
        fi
        その後の処理
    done
    その後の処理
done

上記の「break 深さ数値」はbreakに指定した「深さ数値」のループ制御文の繰り返し処理を抜けだします。

※ループ制御文(for、foreach、while)


ループの深さ付きbreak文のフローチャート

_images/bash_double_loop_break.gif

ラベル付きのものは、主に多重ループを抜ける処理をスマートの書くために使います。

C言語ではこの機能がないため、goto文を使って記述することになります。



ループ深さ付きbreak文の例

bash_double_loop_break.sh

#!/bin/sh

sum=0
for ((i=1; i <= 10; i++))
do
  for ((j=1; j <= 10; j++))
  do
    ((sum=sum+i*j))
    if [ $sum -ge 15 ]
    then
      break 2
    fi
  done
done
echo $sum #=>15

ループ深さ付きbreak文のフローチャート

_images/bash_double_loop_break_exp.gif

6.12. goto文

goto文はありません。

参照:バッチ処理のgoto