基本ルール
決まり文句
1行目に利用するシェルを書く
hello.sh
#!/bin/bash
実行
実行権限を設定してから実行
$ chmod +x hello.sh
$ ./hello.sh
変数
正しい書き方
hello.sh
s="hello"
# こういう書き方ができる
echo $s #hello
echo "$s" #hello
echo "${s}" #hello
# 文字列の連結はくっつけるだけ
echo $s$s # hellohello
echo "$s $s" # hello hello
間違った書き方
以下、まねしないように。
hello.sh
# =の前後にスペースを入れてはいけない。
s = "hello"
# 変数の中身ではなく文字列として表示されてしまう
echo '$s'
四則演算
ポイント
- 計算したい時は`(バッククォート)を使う
- 数値として展開したい変数の前にexprを使う。(この時計算する四則演算記号の前後にスペースを入れる)
- 掛け算やカッコを使う場合は \* のように、記号の前にバックスラッシュが必要(エスケープ)
- readonly とすると変数の上書きができなくなる
hello.sh
x=10
echo $x # 10
echo $x+2 # 10+2
echo `expr $x + 2` # 12
echo `expr \($x + 5\) \* 2` # 30
readonly y=20
y=25 # y: readonly variableというエラーが出る
配列
扱い方
ポイント
- 添字を指定して中身を取り出すには波括弧を使う
- $aで最初の要素が表示される
- ${a[@]}で全ての要素が表示される
- ${#a[@]}で要素数が表示される
hello.sh
a=(2 4 6)
echo $a # 2
echo ${a[0]} # 2
echo ${a[1]} # 4
echo ${a[@]} # 2 4 6
echo ${#a[@]} # 3
# 波括弧を忘れた場合、最初の要素と文字列を連結した文字列になる
echo $a[1] # 2[1]
値の代入、要素の追加
ポイント
- 代入、追加時に波括弧は要らない
- `date`は日付や曜日を要素とした配列になっている。
hello.sh
a=(2 4 6)
a[2]=10
echo ${a[@]} # 2 4 10
a+=(20 30)
echo ${a[@]} # 2 4 10 20 30
d=(`date`)
echo $d # 2014年 11月 12日 水曜日 11時09分30秒 JST
echo ${d[3]} # 水曜日
条件式
条件式の評価
ポイント
- 正常終了は0が返ってくる
- testコマンドで条件式を評価できる(ちなみにtestは[]で置き換え可能)
- $?で、直前に終了した命令が正常終了したかどうかを評価する
比較演算子
- -eq : equal
- -ne : not equal
- -gt : greater than (◯◯より大きい)
- -ge : greater than or equal (◯◯以上)
- -lt : less than (◯◯より小さい)
- -le : less than or equal (◯◯以下)
hello.sh
test 1 -eq 2; echo $? # 1 ←正常でない
test 1 -eq 1; echo $? # 0 ←正常終了
文字列とファイル
文字列の比較演算子
- = : equal
- != : not equal
ファイルの比較演算子
- -nt : newer than
- -ot : older than
- -e : exist (存在しているかどうか)
- -d : directory (ディレクトリかどうか)
論理演算子
- -a : and
- -o : or
- ! : is not
hello.sh
# ファイルが存在するかどうか
test -e hello.sh; echo $? # 0
# 1 = 1 && 2 == 2
test 1 -eq 1 -a 2 -eq 2; echo $? # 0
条件分岐
if文
- ifのあとに条件式を書く
- 条件に合致していればthenからfiまで実行
hello.sh
x=20
if [ $x -gt 60 ]
then
echo "ok!"
elif [ $x -gt 40 ]
then
echo "soso..."
else
echo "ng...."
fi
# ng....
case文
- caseの値に合致したときに処理は)から;;まで
- 何にも当てはまらない時の条件は*)で指定する
hello.sh
signal="red"
case $signal in
"red")
echo "stop!"
;;
"yellow")
echo "caution!"
;;
"green")
echo "go!"
;;
*)
echo "..."
;;
esac
# stop!
ループ処理
while文
- 条件式の間だけdoとdoneの間の処理を行う
基本
hello.sh
i=0
while [ $i -lt 10 ]
do
i=`expr $i + 1`
echo $i
done
途中で抜けたりしたい時
hello.sh
# $iが3の時にはなにもしない
# $iが10より大きくなったらループ終了
i=0
while : # :を使うと常に0(正常終了)を返すので、無限ループになる
do
i=`expr $i + 1`
if [ $i -eq 3 ]; then
continue
fi
if [ $i -gt 10 ]; then
break
fi
echo $i
done
for文
inに続くスペース区切りの値を入れていきdoとdoneの間の処理を実行
hello.sh
for i in 1 2 3 4 5
do
echo $i
done
配列を使いたい時
hello.sh
a=(1 2 3 4 5)
for i in ${a[@]}
do
echo $i
done
コマンド引数の使い方
hello.sh
echo $0 # ファイル名
echo $1 # 1番目の引数
echo $2 # 2番めの引数
echo $@ # 全ての引数
echo $# # 引数の数
ユーザーからの入力を受け付る
readコマンドを使うことで受け取った値を変数に代入できる。以下はkeyという変数にユーザーの入力した値を入れて処理している。
hello.sh
while :
do
read key
echo "you pressed $key"
if [ $key = "end" ]; then
break
fi
done
選択肢で選ばせる
- select というコマンドを使う
hello.sh
select option in CODE DIE
do
echo "you pressed $option"
break;
done
選択肢が表示され、ユーザーは数字で選べる。
1) CODE
2) DIE
#? 1
you pressed CODE
ファイルから入力する
以下は引数に指定したファイルを読み込み、行番号を表示する処理
読み込むデータ。
data.txt
a
aa
aaa
実行ファイル
hello.sh
i=1
while read line # 変数lineに1行ずつ格納される
do
echo "$i: $line"
i=`expr $i + 1`
done <$1 # ここで読み込むファイルを指定(引数)
実行
$ ./hello.sh data.txt
関数
- 関数内で作った変数は関数外でも使用できる。ローカル変数にしたい場合は local i=5 みたいにlocalを使う
- functionは省略可能
hello.sh
# functionは省略可能
hello() {
echo "hello $1 and $2" # hello Mike Tom
i=5
echo $i
}
hello Mike Tom