Bashスクリプトの制御構文

Linux

Linuxのシェルスクリプトである Bash の基本的な制御構文について簡単にまとめておきたいと思います。自分用の備忘録なので細かい説明は省いています。

宣言 (statements)

シバン / シェバン (shebang)

シバンあるいはシェバン (shebang) とは、スクリプトファイルの1行目に記述する #! から始まる宣言のことで、スクリプトが読み込むインタプリタを指します。

#!/bin/sh とか #!/bin/bash みたいに書かれている部分です。

変数 (variable)

等号の前後にはスペースを入れられません (例: ABC = 100)

特に指定しない限り、変数は全て大域変数になります。

ABC=100
echo ${ABC}

局所変数(ローカル変数)の指定、declaretypeset を使います。

# 文字列変数
declare str

# 数値変数
declare -i num

# 配列変数
declare -a array

# また local でも局所変数指定が可能
local -i num

定数 (constant)

定数の指定には readonly を使う方法、local -r を使う方法、declare -r を使う方法の3つがあります。readonly をグローバル定数に、local -r をローカル定数にした方がわかりやすいかもしれません。

readonly XYZ
local -r xyz
declare -r xyz

配列 (array)

配列の代入方法その1

arrayA[0]=10
arrayA[1]=20
arrayA[2]=30

# 10と表示される
echo ${arrayA[0]}

配列の代入方法その2

arrayA=([0]=10 [1]=20 [2]=30)

# 10と表示される
echo ${arrayA[0]}

配列の代入方法その3

arrayA=(10 20 30)

# 10と表示される
echo ${arrayA[0]}

配列を使った例

# arrayA[0]、arrayA[1]、arrayA[2] に格納されている数字の合計を表示する
arrayA=(10 20 30)
echo $((arrayA[0]+arrayA[1]+arrayA[2]))


# 配列のサイズを取得
${arrayA[@]}
${arrayA[*]}

#配列の要素の数を取得
${#arrayA[@]}
${#arrayA[*]}

関数 (function)

関数は以下の3つの指定方法があります。引数は $1 $2 $3 と指定します。

function 関数名(引数) {
    ~ 内容 ~
}

function 関数名 {
    ~ 内容 ~
}

関数名(引数) {
    ~ 内容 ~
}

2つの引数を足し算した結果をローカル変数 var に格納して echo でその変数の中身を表示するコードです。以下の結果は50になります。

function sum {
    local -i var=$(($1+$2))
    echo "result = $var"
}
sum 20 30

ワイルドカード (wild card)

? -- 任意の一文字
* -- 任意の文字列

[abc] -- a, b, c のいずれか
[.,;] -- ピリオド,コンマ,セミコロンのいずれか
[-_]  -- ダッシュ又はアンダースコア
[a-c] -- a, b, c のいずれか
[a-z] -- 小文字のアルファベットすべて
[!0-9] -- 0 から 9 以外の文字
[0-9!] -- 0 から 9 までの数字とエクスクラメーション
[a-zA-Z]      小文字と大文字のアルファベットすべて
[a-zA-Z0-9_-]  すべてのアルファベット,数字,アンダースコア,ダッシュ

ls .foo.?

ls foo.*

ls foo.[ch]
  foo.c foo.h

ls foo.[!ch]*
foo.chのいずれでもない文字

制御構文 (control flow statements)

if / elif / else文

基本的に if [ 条件式 ] が用いられますが、個人的には if [[ 条件式 ]] を使ったほうが読みやすい気がするので if [[ 条件式 ]] に統一しています。

書き方その1

if [[ 条件式 ]]; then
  echo 1

elif [[ 条件式 ]]; then
  echo 2

else
  echo 3

fi

書き方その2

if [[ 条件式 ]]
then
  echo 1

elif [[ 条件式 ]]
then
  echo 2

else
  echo 3

fi

case文

他のプログラム・スクリプト言語のswitch文と同等。;;は処理を抜けるという意味で break; と同等。

case 変数 in
'値1')
    ~ 処理 ~ ;;

'値2')
  ~ 処理 ~ ;;

*)
  ~ 処理 ~ ;;
esac

select文

以下だと「2」と入力するまで選択画面がループします。$PS3というシェル変数を設定すれば、好きなメッセージを出力できます。また、入力された値は $REPLY に格納される。

PS3='この一覧から正解を選択してください'
select i in sample1 sample2 sample3 sample4 sample5; do

    if [[ $i == 'sample2' ]]; then
        echo '正解!'
        break;

    elif [[ 5 -lt $REPLY ]]; then
        echo '数字が選択肢にありません'

    else
        echo '不正解'

    fi

done

for文

書き方その1

for ((初期化; ループ条件; 式)); do
    ~ 内容 ~
done

書き方その2

for ((初期化; ループ条件; 式))
do
    ~ 内容 ~
done

for文を使った例

ary=("xxx" "yyy" "zzz")

for ((i=0; i<=2; i++)); do
    echo "$i = ${ary[i]}"
done

for … in文

書き方その1

for 変数 in リスト; do
  ~ 内容 ~
done

書き方その2

for 変数 in リスト
do
  ~ 内容 ~
done

for … in文を使った例

ary=("xxx" "yyy" "zzz")

for i in ${ary[@]}; do
    echo "$i = ${ary[i]}"
done

# 出力結果
xxx = xxx
yyy = yyy
zzz = zzz

while文

条件式が真の間、処理を繰り返します。

書き方その1

while [ 条件式 ]; do
    〜 内容 〜
done

書き方その2

while [ 条件式 ]
do
    〜 内容 〜
done

while文を使った例

n=1
while [[ $n -le 10 ]]; do
    echo "$n true"
    ((++n))
done

until文

条件式が偽の間、処理を実行し続けます。条件式が真の間、処理を繰り返すwhile文とは真逆です。

書き方その1

until [ 条件式 ]; do
    〜 内容 〜
done

書き方その2

until [ 条件式 ]
do
    〜 内容 〜
done

演算子 (operators)

数値演算子 (arithmetic operators)

  +   # 加算
  -   # 減算
  *   # 乗算
  /   # 除算
  %   # 剰余


シェルスクリプト実践テクニック~bash編

Powered by Open Sources
BASHでの変数について
BASHでの変数について - ファイヤープロジェクト
BASHスクリプトにおける変数の取扱について説明する...

ビット演算子 (Bitwise operators)

  <<  # 左へビットシフト
  >>  # 右へビットシフト
  &   # 論理積
  |   # 論理和
  ~   # 論理否定
  !   # 論理否定
  ^

代入演算子 (assignment operators)

  x = y    # x に y を代入
  x += y   # x = x + y と同等
  x -= y   # x = x - y と同等
  x *= y   # x = x * y と同等
  x /= y   # x = x / y と同等
  x %= y   # x = x % y と同等

  x **= y   # x = x ** y に同じ
  x //= y   # x = x // y に同じ
  x &= y    # x = x & y に同じ
  x |= y    # x = x | y に同じ
  x ^= y    # x = x ^ y に同じ
  x <<= y   # x = x << y に同じ
  x >>= y   # x = x >> y に同じ

  # インクリメント
  let "++num"
  ((++num))

  # デクリメント
  let "--num"
  ((--num))

論理演算子 (logical operators)

# 論理 NOT
!条件

# 論理 AND
if [ 条件1 ] && [ 条件2 ]

# 論理 OR
if [ 条件1 ] || [ 条件2 ]

関係演算子 (relational operators)

${num1} -eq ${num2}    ( num1 == num2 )
${num1} -ne ${num2}    ( num1 != num2 )
${num1} -lt ${num2}    ( num1 <  num2 )
${num1} -le ${num2}    ( num1 <= num2 )
${num1} -gt ${num2}    ( num1 >  num2 )
${num1} -ge ${num2}    ( num1 >= num2 )

-n str  文字列が空ではない
-z str  文字列が空である

str1 == str2  文字列が等しい場合に真
str1 != str2  文字列が等しくない場合に真

[bash][if]比較 - infoaofd

Google Sites: Sign-in
Access Google Sites with a personal Google account or Google Workspace account (for business use).

ヒアドキュメント (Here document)

echoで出力すると以下の様になり面倒。

#!/bin/sh
echo "<HTML>"
echo "<HEAD>"
echo "<TITLE></TITLE>"
echo "</HEAD>"
echo "<BODY>"
echo "<H1></H1>"
echo "<P>"
echo "</P>"
echo "</BODY>"
echo "</HTML>"

しかしヒアドキュメントを使うと、以下のように簡潔なコマンドで出力が可能になります。

#!/bin/sh
cat << EOS
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<H1></H1>
<P>
</P>
</BODY>
</HTML>
EOS

コメントアウト (comment out)

1行コメントアウトする場合

# このコメントは表示されません

複数行に渡るコメントアウト。何もせず終了コード0を返す : とヒアドキュメントの組み合わせ。

: << ___CommentOut

  echo "このコマンドは実行されません"
  echo "これは表示されまません"

___CommentOut

その他

if [ "$a" -eq 24 ] && [ "$b" -eq 47 ]


# 結果をファイルに出力
  bash script.sh > file.txt

# 文法チェック
  bash -n script.sh

# デバック
  bash -x script.sh

参考にさせていただいたサイト様

LINUX testコマンドについて - Qiita
概要一言で言うと条件を判定するコマンドです。記法としては以下のように書くことができます。test 条件条件の部分には判定したい条件を書き真の場合: 0偽の場合: 1を返します。(※ …

コメント