bashで日付チェックするシェルを作成

会社でようやくblog活用の話が出てきましたよ、bonlifeです。隣の席の先輩が何やらリーダーに任命されてましたよ。頑張ってくださいませ。という話は置いておきまして。日付チェックシェル、ついに第3弾です。今回はLinuxユーザーにはお馴染みのbashで作ってみました。アクセス解析を見てたら「bash 日付チェック」なんてキーワードでこの辺境の地にたどり着いた人もいたようなので、kshを次回にしてbashを先にやってみました。

参考情報ですが、以前作成したシェルは以下のリンク先にてご確認いただけます。

checkdate

#! /bin/sh

# usage : checkdate YYYYMMDD

# エラー処理用関数定義

error_exit () {
# echo "Error exit."
  exit 1 
}

# 引数の数をチェック
# 引数が1つでない場合、エラー終了
# エラー終了時は error_exit を呼び出す

if [ $# -ne 1 ];
then
# echo "The number of arguments is incorrect."
  error_exit
fi

# 桁数チェック
# 8桁でない場合、エラー終了

if [ `expr length $1` -ne 8 ];
then
# echo "Argument length check error."
  error_exit
fi

# 値の妥当性チェック (簡易チェック)

if [ -z `echo $1 | egrep '^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$'` ];
then
# echo "Basic argument check error."
  error_exit
fi

# 入力値を分割して変数にセット

YEAR=`expr substr $1 1 4`
MONTH=`expr substr $1 5 2`
DAY=`expr substr $1 7 2`

# 日のチェック ( 詳細 : 月ごとの最終日と閏年の考慮 )

ENDDAY=(31 28 31 30 31 30 31 31 30 31 30 31)
LASTDAY=${ENDDAY[$MONTH-1]}

if [ $MONTH -eq 2 -a `expr $YEAR % 4` -eq 0 -a `expr $YEAR % 100` -ne 0 ];
then
    LASTDAY=`expr $LASTDAY + 1`
elif [ $MONTH -eq 2 -a `expr $YEAR % 400` -eq 0 ];
then
    LASTDAY=`expr $LASTDAY + 1`
fi

if [ $DAY -gt $LASTDAY ];
then
# echo "Day check check error."
  error_exit
fi

# 上記全てのチェックで問題がなければ戻り値 0 で終了

exit

ついに関数、配列の両機能を持ったシェルに出会えました。やはりBourne Shellの配列もどきよりずっとスッキリしましたね。一時ファイルを作る必要もなくなったので、不要ファイルの削除などの処理もいらなくなり、エラー時の終了処理を関数にする必要がなくなってしまいましたよ。とか言いつつ、無理やり関数にしてたりするのですが。Bourne Shellでは「-z」はファイルがゼロバイト長かどうかをチェックするものだったのですが、bashではテキスト(String)がゼロバイト長かどうかをチェックするのに使うんですね。「expr」で文字列の操作(length、substr)などが使えるのはとっても便利です。今までで一番シンプルで分かりやすいソースになったと思います。
日付のチェックを行った結果、与えられた文字列が妥当な日付であれば戻り値0を返し、不正な日付であれば戻り値1を返しますので、別のシェルから呼び出して、戻り値によって処理を分けてみてください。bashでは戻り値は「$?」で取得できます。普段使っているcshでは戻り値の取得は「$status」変数を使うのが一般的だったので、最初bashでも同じことを試してしまい、戻り値が正しくセットされていないかと思い、焦ってしまったのは秘密です。
よくプログラミングが得意っぽい人たちが同じ処理を複数の言語で書いてソースの美しさや実行速度について語っている気分が少しだけ分かったような気がします。よーし、今度こそkshにチャレンジ!