Posted at

シェルスクリプトの基礎知識まとめ

More than 3 years have passed since last update.


基本ルール


決まり文句

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