サイト名変更・お引越しのお知らせ

【入門者向け】シェルスクリプトの基本文法チュートリアル

シェルスクリプトの基本をマスターするために、チュートリアル形式で解説していきます。

モグモグさん

初心者の方や、なんとなーく知っている方向けです。

一周やってみると基本が抑えられます。

シェルスクリプトとは?に関してはこちらの記事で解説しているので、必要であれば参照ください。

この記事でわかること
  • シェルスクリプトの基本が理解できて使えるようになる

モグモグさん

実際に手を動かしながらやってみると理解が深まりますので

やってみてください。

実行

上記のマークの箇所は実際に実行したりコードを書いてみましょう。

注意

本記事は、基本的にbashをベースとしています。

基礎を押さえる上では、bashで良いと思います。

Linux(CentOS)環境を準備

まずは手元で試すための環境を作成します。

モグモグさん

環境がすでにある方や手元で試す必要がない方は、スキップしてください。

こちらの記事を参考に、CentOSの環境を作成しましょう。

Dockerで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は変更不可能"

実行

unsetreadonlyの挙動を確認しましょう!

$ 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

まとめ

モグモグさん

お疲れ様でした!

本チュートリアルを一通り行うことで、ある程度基礎を抑えれると思います。

実際、他にも色々な書き方がありますので気になる方は、いろいろ調べてみましょう。