シェル(Bash)

3.6.4 シェルスクリプト

1.   シェルスクリプトの基本

エイリアスは、長くても一行程度ですむようなコマンドの別名を定義するのに使う。さらに長い一連の命令をひとつのコマンドとするには、 通常シェルスクリプトと呼ばれるファイルを作成する。

例えば、以下のような内容のファイルをls.shという名前にして作ってみよう。

#!/bin/sh

# まず現在のディレクトリを調べる。
echo -n "現在のディレクトリは "


pwd


# どんなファイルがあるかを表示する。
echo "以下のファイルが見付かりました。"


ls
次に、以下を実行する. 

$ chmod +x ls.sh

これは、ls.sh を実行可能なファイルにする命令である。(実行許可を取り消すには$ chmod -x ls.shとする。) ここで ~/ls.shを実行すれば、現在のディレクトリ名と、中にある ファイル一覧が表示される(echo は 文等を表示する命令で、-n は改 行しないためのオプション)。 このように、実行したい命令をずらずらと書いたファイルをつくり、 ファイルの頭に#!/bin/shという行をいれれば、 記述した命令を順次実行できるシェルスクリプトになる。

また、各行で記号#があるとき、それ以降の文字はコメント文とみなされ て無視される。

2.   シェルスクリプトの引数

シェルスクリプトの引数は$0,$1,...で参照できる。引数の数は $#で参照できる。



#!/bin/sh


echo "これが第0引数" $0
echo "これが第1引数" $1
echo "これが全ての引数" $@ 

3.   文字変数

Bash スクリプトで文字変数を定義するには'='を使って定義すればよい。 以下の例では、変数FNAMEにtest.cが、変数ARGに引数$1が 変数BDIRに/usr/binが代入される。


FNAME="test.c"
ARG="$1"
BINDIR="/usr/bin"

ここで、=の両側にはスペースが入らないことに注意! 変数の値を参照するには、変数名に$をつける。 また、変数名を{}で囲むことが多い。(必ずしも囲む必要はないが、 変数名の範囲を明確にできるのでトラブルがおきにくい)

以下は、上のように定義した変数を参照する例である。



echo "FNAMEは" ${FNAME} ", ARGは" ${ARG} "です"
ls ${BINDIR}

4.   変数の操作

Bash スクリプトでは変数の値を簡単に操作できる機能がある。 以下ではその一部を紹介する。

命令 意味
${VAL%word} 変数${VAL}の値後のろからword に合致する最小部分を削除した値
${VAL%%word} 変数${VAL}の値の後ろからword に合致する最長部分を削除した値
${VAL#word} 変数${VAL}の値の頭からword に合致する部分を削除した値
${VAL##word} 変数${VAL}の値の頭からword に合致する部分を削除した値

以下はシェルスクリプトでの使用例である。


#!/bin/sh
DIR=/usr/local/bin
echo ${DIR%/*}
echo ${DIR%%/*}
echo ${DIR#/*/}
echo ${DIR##/*/}

実行結果は以下の通り


/usr/local

local/bin
bin

5.   シェルスクリプトの終了

シェルスクリプトは exitが実行された時終了する。 正常終了の時には exit 0、異常終了の時には exit 1 (0以外を指定)する場合が多い。

6.   if 文

Bashスクリプトでのif構文は以下の通り。


if [ 条件文 ] ; then
...
else
...
fi

以下に条件文の一部を示す。

条件文 意味
-d <文字> <文字>の名前のディレクトリがある時真
-f <文字> <文字>の名前のファイルがある時真
<文字1> = <文字2> <文字1><文字2>が等しい 時真 ('='の両側にスペースがあることに注意)
<文字1> != <文字2> <文字1><文字2>が異 なる時真
! <条件文> <条件文>が偽であるときに真 (NOT)


7.   for 文

Bashスクリプトでのfor構文は以下の通り。


for <変数> in <値1> <値2> ....; do
...
done

<変数><値1> <値2> ....が順に代入され、do と done で囲ん だ部分が繰り返し実行される。

以下はファイル a, b, c をそれぞれソートして a2, b2, c2 にするスクリプト である。


for i in a b c; do
   sort $i > ${i}2
done

値を並べるかわりにあるコマンドの出力を用いることもできる。 以下は ls *.datで表示されるファイルについて、先の例と同様の処理を 行うスクリプトである。(コマンドは ` で囲むこと)


for i in `ls *.dat`; do
   sort $i > ${i}2
done

8.   case文

ある変数の値に応じて様々な処理を分岐させる時には、if 文を使うよりも case 文を使う方が便利なことが多い。


case <変数> in 
        <値1>) 文1
                ;;
        <値2>) 文2
                ;;
        *) 文(default)
                ;;
esac


変数
値1の時は文1が、 値2の時は文2が、いずれの値にも該当しないときには、 文(default)が実行される。 各文の終りには ;; を記述すること。;; が読み込まれると、case 文は終了する。

以下は、引数で与えたファイルの拡張子に応じて解凍を行う例である。 ("|"は OR を表す)

case "$1" in 
        *.tar.gz|*.tar.bz2) tar xzvf $1  ;;
        *.gz) gunzip $1 ;;
        *.bz2) bunzip2 $1 ;;
esac

9.   参考文献

シェルスクリプトは大変強力なプログラミング言語である。詳細を知るには 以下の書籍等で各自自習すること。

川村正樹「BASH入門」秀和システム