##概要
前回の記事では、シェルスクリプトの基本(順次実行)のみ触れました。
今回は、シェルスクリプトを構成す3つの重要な要素(条件分岐、繰り返し、サブルーチン)についてメモしておく。
##実行環境
- macOS BigSur 11.4
- CentOS7 (macOS上でLinux環境を構築する方法はこちらを参考にしました)
##条件分岐
###1. if, else
if, else文を用いて条件分岐を行う。
基本形は以下の通り。
# 書式
if [ 条件式1 ]; then # 条件式を囲む左右の[]に一個ずつスペースが必要!
# 条件1が成立する場合の処理
elif [ 条件式2 ]; then
# 条件2が成立する場合の処理
else
# どの条件にも合致しない場合の処理
fi # ifの逆で終わる
上記の書き方は
if test 条件 ; then ...
の省略形。
比較演算子を用いて、様々な条件で値を比較したり、文字列を比較することもできる。
複数の条件を組み合わせることもできる。
例)
#!/bin/bash
# 変数xに入力されたデータを読み込む
read x
# xの値によって条件分岐
if [ $x == 0 ]; then
echo "x is zero."
elif [ $x == "A" ]; then
echo 'x is "A".'
elif [ $x -ge 1 ] && [ $x -lt 10 ]; then
echo '1 <= x < 10'
else
echo 'None'
fi
また、値や文字列だけでなく、ファイルの種類なども条件として与えられる。
例)
#!/bin/bash
read name
# name変数で指定されたものがファイルかディレクトリか、その他(シンボリックリンクなど)かどうかを条件分岐で確かめる
if [ -d ${name} ]; then # ディレクトリ
echo "${name} is directory"
elif [ -f ${name} ]; then # ファイル
echo "${name} is file"
else # その他
echo "${name} doesn't exit"
fi
if文の書き方の基本はこちら、比較演算子などの例をめっちゃやってくれてるのがこちらで、大変参考になりました。
###2. case
一対多の分岐を記述するための文。
指定した変数の値に対して、複数の条件分岐を書きやすい。
# 書式
case 変数 in
値 A)
処理1;;
値 B)
処理2;;
*) # どの条件にもマッチしなかった場合の処理は*)を用いる
処理3;;
esac # caseの逆で終わる
引数を比較に用いることで、テストファイルなども作成しやすい。
例)
#!/bin/bash
case $1 in
1)
echo "Arguent is 1.";;
A)
echo "Argument is A.";;
*)
echo "Argument is not A or 1.";;
esac
##繰り返し
###1. for
100回など大きな回数で同じ処理を繰り返し行う際などに用いられる。
# 書式
for 変数 in 値のリスト
do
# 処理
done
例)
$ ls
test1 test2 test3 test4 test5
# コマンドラインからfor文を直接記述している
$ for i in `ls` # ``で囲むとコマンドの実行結果を値リストとして扱うことができる
> do
> echo $i
> done
test1 # lsコマンドの実行結果が1行ごとに出力される
test2
test3
test4
test5
###2. while, until
while
は条件が成立している間、until
は条件が成立していない間ループを繰り返す。
# 書式
while / until 条件式
do
# 処理
done
C言語のように値をインクリメントしてループ処理をする場合は、expr
コマンドを用いて計算を行う。
計算式や論理式を評価するexpr
コマンドの詳細はこちらを参考にさせていただきました。
$ count=1
$ while [ $count -lt 10] # countが10未満ならば処理を行う
> do
> echo "Count is $count"
> count=`expr $count + 1` # exprコマンドで値をインクリメントする
> done
Count is 1. # 1~9までが表示される
Count is 2.
Count is 3.
Count is 4.
Count is 5.
Count is 6.
Count is 7.
Count is 8.
Count is 9.
###3. select
値のリストに対し、インデックスを割り当て、入力されたインデックスの値に対応するデータに対して処理を行う。
# 書式
select 変数 in 値のリスト
do
# 処理
done
1) 値1 # 値のリストが表示される
2) 値2
3) 値3
...
$? n # 番号を入力
# nに対応する処理
$ # `Ctrl+C`で終了
例)
$ select name in "apple" "banana" "orange"
> do
> echo "Name is $name"
> done
1) apple
2) banana
3) orange
$? 2 # 2で"banana"を指定
Name is banana
$
###4. break, continue
break
はループを抜け、continue
はループの最初に戻る。
例)
while true
do
echo "Continue? (y/n)"
read input
case $input in
n) break # nが入力された場合、ループを抜ける
;;
y) continue # yが入力された場合、ループの最初に戻る
;;
*) echo "Please input y or n." # y, n以外が入力された場合、echo以降の文字列を出力してループを繰り返す
;;
esac
done
実行結果
$ ./sample.sh
Continue? (y/n)
a
Please input y or n.
Continue? (y/n)
y
Continue? (y/n)
n
$
##サブルーチン(関数)
加算や配列の入れ替えなど、一連の処理をまとめて、再利用できるようにしたもの。
C言語とかやってるとすぐわかるはず。
# 書式
関数名 ()
{
# 処理
return 変数名 # 戻り値
}
##番外編 : デバッグ
shコマンドに-xオプションをつけると、各行のコマンドや変数の中身を表示しながらスクリプトを実行する。
$ sh -x ./sample.sh
##終わりに
こういうプログラミングの基礎構造みたいなやつは、例を見ながら自分で、適当に条件や値を変えたり、繰り返しと条件分岐を組み合わせてみたりしながらやるのが一番わかりやすいと思います。
##参考文献
この記事は以下の情報を参考にして執筆しました。