簡易的に引数をチェックする(シェルスクリプト)

課題

例えば個人的に利用するようなスクリプトでは、厳格な引数チェックを行う必要はないだろう。 一方で、明らかな誤りを弾くために、ある一定のレベルでは引数チェックを行いたいときがある。 どのような引数チェックができるのか。

解決法

引数の数をチェックする

チェックをしたいということは、当然ながら何らかの引数を指定しているはずである。 まずはこの引数の数が想定通りであることを確認できる。

$ cat paramcheck.sh 
#!/bin/sh
set -eu

# 引数が1個であることを確認する
[ $# != 1 ] && echo "error: invalid number of args" 1>&2 && exit 1

echo "Passed all parameter checks"

上記のチェックをパスする場合とそうでない場合は以下の通り。

$ ./paramcheck.sh param
Passed all parameter checks
$ echo $?
0
$ ./paramcheck.sh 
error: invalid number of args
$ echo $?
1

ファイルの拡張子をチェックする

引数にファイルを指定するとき、ファイルの拡張子が確定しているならば、その拡張子をチェックすることができる。

$ cat paramcheck.sh 
#!/bin/sh
set -eu

# 引数が1個であることを確認する
[ $# != 1 ] && echo "error: invalid number of args" 1>&2 && exit 1

# 拡張子が.txtであることを確認する
case "$1" in
  *.txt) break ;;
  *)     echo "error: invalid extension" 1>&2 && exit 2
esac

echo "Passed all parameter checks"

上記のチェックをパスする場合とそうでない場合は以下の通り。

$ ./paramcheck.sh param.txt
Passed all parameter checks
$ echo $?
0
$ ./paramcheck.sh param
error: invalid extension
$ echo $?
2

ファイルの読み出し可否をチェックする

引数にファイルを指定するとき、そのファイルから読み出しを行うことが多いだろう。 そのファイルが実際に存在して、読み出すことができることをチェックすることができる。

$ cat paramcheck.sh 
#!/bin/sh
set -eu

# 引数が1個であることを確認する
[ $# != 1 ] && echo "error: invalid number of args" 1>&2 && exit 1

# 拡張子が.txtであることを確認する
case "$1" in
  *.txt) break ;;
  *)     echo "error: invalid extension" 1>&2 && exit 2
esac

# ファイルが読み出し可能であることを確認する
[ ! -r "$1" ] && echo "error: cannot be read" 1>&2 && exit 3

echo "Passed all parameter checks"

上記のチェックをパスする場合とそうでない場合は以下の通り。

$ ls
param.txt     paramcheck.sh
$ ./paramcheck.sh param.txt 
Passed all parameter checks
$ echo $?
0
$ ls
param.txt     paramcheck.sh
$ ./paramcheck.sh qaram.txt 
error: cannot be read
$ echo $?
3

所感

何もチェックを行わないより、少しでもチェックを行う仕組みを導入しておくことで、驚くほど効果がある。 また、スクリプト実行時に精神的に安心感が生まれる(明らかに変な引数なら自動的に弾いてくれる)ので、穏やかな気持ちでスクリプトを書きたい人には何らかのチェックを行うことをおすすめしたい。