シェルスクリプトの基本をマスターするために、チュートリアル形式で解説していきます。
モグモグさん
初心者の方や、なんとなーく知っている方向けです。
一周やってみると基本が抑えられます。
シェルスクリプトとは?に関してはこちらの記事で解説しているので、必要であれば参照ください。
- シェルスクリプトの基本が理解できて使えるようになる
モグモグさん
実際に手を動かしながらやってみると理解が深まりますので
やってみてください。
実行
上記のマークの箇所は実際に実行したりコードを書いてみましょう。
本記事は、基本的にbashをベースとしています。
基礎を押さえる上では、bashで良いと思います。
Linux(CentOS)環境を準備
まずは手元で試すための環境を作成します。
モグモグさん
環境がすでにある方や手元で試す必要がない方は、スキップしてください。
こちらの記事を参考に、CentOSの環境を作成しましょう。
Bashを起動
下記コマンドを実行し、Bashを起動しましょう。
$ docker run -it --rm centos /bin/bash
モグモグさん
これで準備完了です!
exit
と入力すれば、bashから抜けます。
基本のキ
まずは基本のキを抑えていきます。
早速ファイルを作ってみましょう。
シェルスクリプトのファイル拡張子は、.sh
です。
実行
#!/bin/sh
echo "Hello"
ファイルを作成したら、実行します。
shコマンド
を使うか、bashコマンド
もしくは.コマンド
で実行可能です。
Helloと出力されればOKです!
実行
$ sh sample.sh
$ bash sample.sh
$ . sample.sh
実行コマンドで動作環境が変わったりしますので、
気になる方は後ほど調べてみましょう。
この記事ではそこまで細かくは踏み込まないようにしています。
!/bin/sh
は、シェバンまたはシバン(shebang)と呼びます。
これは、スクリプトが実行される環境を指定しています。
ここに関しても色々な考え方がありますが、学習を深めていく中で意味を理解していきましょう。
コメント
コメントは、#
から始めます。
複数行の場合は、<<
と任意の文字列
で囲います。
実行
#!/bin/sh
# コメント
<< COMMENT
echo "コメントアウト"
複数行コメント
COMMENT
実行
$ sh comment.sh
全てコメントなので、何も出力されない
入力と出力
入力は、read
で、出力は先ほどから使っているecho
を使います。
実行
#!/bin/sh
echo "何歳ですか?"
read AGE
echo "あなたは$AGE歳ですね"
実行
年齢を入力すると出力されます。
$ sh input_output.sh
何歳ですか?
25
あなたは25歳ですね
変数
続いて変数の解説です。
通常の変数、特殊変数があるのでそれぞれ解説していきます。
通常の変数
- 変数の名前は、半角英数字と_が使える。
=
のあとはスペースがない点は注意。- 定義した変数には、
$
でアクセス可能。(${}
でも可) readonly
をつけると変更不可能な変数になる。unset
を使うと、readonly
ではない変数をリセットできる。
実行
#!/bin/sh
val="変数1"
VAL="変数2"
echo "変数1を出力 => $val"
echo "変数2を出力 => ${VAL}"
unset val
echo "unsetした変数1を出力 => $val"
readonly val3="変数3"
val3="readonlyは変更不可能"
実行
unsetやreadonlyの挙動を確認しましょう!
$ sh val.sh
変数1を出力 => 変数1
変数2を出力 => 変数2
unsetした変数1を出力 =>
val.sh: line 12: val3: readonly variable
安全性を高めるために、set -eu
を呼ぶことがおすすめです。
set -e : エラーが発生した場合に処理を止める。
set -u : 定義していない変数を参照した場合にエラーを発生させる。
本記事でも以降はつけるようにしていきます。
特殊変数
$に続く変数ではいくつか特殊変数と呼ばれる変数があります。
引数系は特によく使うので覚えておきましょう!
変数 | 意味 |
$0 | スクリプト名 |
$1 – $9 | 引数 (例: $1は1つ目の引数) |
$# | 引数の数 |
$* | 引数を全て文字列にする |
$? | 直前に実行したコマンドの結果 (0: success, 1: failure) |
$$ | プロセスID |
実行
#!/bin/sh
set -eu
echo "スクリプト名: $0"
echo "引数1: $1, 引数2: $2"
echo "引数の総数: $#"
echo "引数全て: $*"
echo "コマンドの結果: $?"
echo "プロセスID: $$"
実行
それぞれ値が入っているか確認しましょう。
$ sh sp_val.sh hoge fuga piyo
引数1: hoge, 引数2: fuga
引数の総数: 3
引数全て: hoge fuga piyo
コマンドの結果: 0
プロセスID: 55
if文
if [ 条件 ] then 内容 fi
が基本的な書き方。elif
で条件を加える。else
でそれ以外の条件となる。- ORの場合は、
if [ 条件1 ] || [ 条件2 ]
となる。 - ANDの場合は、
if [ 条件1 ] && [ 条件2 ]
となる。
thenで一行を使うのではなく、セミコロンを使うケースが多いのでその記法で書きます。
if [ 条件 ]; then
実行
#!/bin/sh
set -eu
# ifのみのパターン
val="変数a"
if [ $val = "変数a" ]; then
echo "valは変数a"
fi
# elifを使ったパターン
val="変数b"
if [ $val = "変数a" ]; then
echo "valは変数a"
elif [ $val = "変数b" ]; then
echo "valは変数b"
fi
# elseを使ったパターン
val="変数c"
if [ $val = "変数a" ]; then
echo "valは変数a"
elif [ $val = "変数a" ]; then
echo "valは変数b"
else
echo "valは変数c"
fi
# ORパターン
val="変数a"
if [ $val = "変数a" ] || [ $val = "変数b" ]; then
echo "valは変数aもしくは変数b"
fi
# ANDパターン
val="変数a"
val2="変数b"
if [ $val = "変数a" ] && [ $val2 = "変数b" ]; then
echo "valは変数aかつval2は変数b"
fi
実行
正しい出力がされているか確認しましょう。
$ sh condition.sh
valは変数a
valは変数b
valは変数c
valは変数aもしくは変数b
valは変数aかつva2は変数b
switch文
case 変数 in 条件・値) コマンド ;; esac
が基本的な書き方。
実行
引数で渡した環境を出力するようなシェルを作ってみます。
#!/bin/sh
set -eu
target_env=$1
if [ $target_env != "production" ] && [ $target_env != "staging" ]; then
echo "productionかstagingを引数に渡してください"
exit 1
fi
case $target_env in
"production")
echo "production環境です"
;;
"staging")
echo "staging環境です"
;;
esac
実行
$ sh switch.sh production
production環境です
配列
(hoge fuga piyo)
で定義できる。array[0]
のように添字でアクセス。array[*]
もしくはarray[@]
で全ての中身を取得できる。
実行
#!/bin/sh
set -eu
array=(hoge fuga piyo)
echo "1つ目の中身: ${array[0]}"
echo "全ての中身: ${array[*]}"
実行
$ sh array.sh
1つ目の中身: hoge
全ての中身: hoge fuga piyo
四則演算
expr
を使うか、$(())
のような算術式展開(bash)を使います。
基本的な四則演算を使ってみましょう。
実行
#!/bin/sh
set -eu
echo $((10+5)) # 足し算
echo $((5-2)) # 引き算
echo $((10*8)) # かけ算
echo $((10/2)) # 割り算
echo $((5%2)) # 剰り
echo `expr 10 + 5` # 足し算
echo `expr 5 - 2` # 引き算
echo `expr 10 \* 8` # かけ算
echo `expr 10 / 2` # 割り算
echo `expr 5 % 2` # 剰り
実行
正しい結果が返ってきているかどうか確認しましょう。
$ sh operations.sh
15
3
80
5
1
15
3
80
5
1
比較演算子
- 主に
[]
の条件式の中で使える比較演算子。 - 比較対象は数字。
式 | 意味 |
-eq | イコール |
-ne | イコールではない |
-gt (-ge) | e.g. [ $a -gt $b ] $aは$bよりも大きい -geは、大きいもしくはイコール |
-lt (-le) | e.g. [ $a -lt $b ] $aは$bよりも小さい -leは、小さいもしくはイコール |
モグモグさん
具体的なコードはループの章で扱います!
ループ
whileループ
実行
#!/bin/sh
set -eu
num=0
while [ $num -lt 5 ]
do
echo $num
num=`expr $num + 1`
done
実行
$num
が5より小さい場合にループするので下記のような結果になればOKです。
$ sh while.sh
0
1
2
3
4
until
実行
#!/bin/sh
set -eu
num=0
until [ $num -gt 5 ]
do
echo $num
num=`expr $num + 1`
done
実行
$num
が5より大きくない場合にループするので下記のような結果になればOKです。
$ sh until.sh
0
1
2
3
4
5
for
実行
#!/bin/sh
set -eu
for num in 0 1 2 3 4 5
do
echo $num
done
実行
$ sh for.sh
0
1
2
3
4
5
関数
実行
#!/bin/sh
set -eu
function say_hello () {
echo "hello"
}
# 呼び出し
say_hello
# functionは省略ができる
say_hi () {
echo "hi"
}
# 呼び出し
say_hi
# 引数を受け取るパターン
call_my_name () {
echo "name is $1"
}
# 呼び出し
call_my_name mogumogu
実行
$ sh func.sh
hello
hi
name is mogumogu
まとめ
モグモグさん
お疲れ様でした!
本チュートリアルを一通り行うことで、ある程度基礎を抑えれると思います。
実際、他にも色々な書き方がありますので気になる方は、いろいろ調べてみましょう。