Bash 組み込みの getopts コマンドを使用すると、シェルスクリプトに渡されたコマンドラインオプション (-a など)を解析することができます。
getopts は 1 文字のオプションしか扱えないことに注意してください。
引数なしのオプション
下記は getopts の基本的な使用例です。
getopts のオプション文字列として abc を指定することにより、このシェルスクリプトで、-a、-b、-c という 3 種類のオプションを受け取れるようになっています。
ユーザーが指定したオプションが、1 文字ずつ opt 変数に格納されるので、その値で case による分岐処理を行います。
#!/bin/bash
while getopts 'abc' opt; do
case "${opt}" in
a) echo "オプション -a を指定しました" ;;
b) echo "オプション -b を指定しました" ;;
c) echo "オプション -c を指定しました" ;;
esac
done$ ./sample.sh -a
オプション -a を指定しました
$ ./sample.sh -a -c
オプション -a を指定しました
オプション -c を指定しました
$ ./sample.sh -x
./sample.sh: illegal option -- x
最後の実行例から分かるように、getopts は定義されていないオプション (-x) を指定したときに、自動的にエラーメッセージ (illegal option) を出力します。
このエラー出力を抑制するには、次のように、オプション文字列の先頭に : を付け、:abc のように指定します。
不正なオプションが指定された場合は、opt 変数の値が ? になるので、自分でエラー処理を行うことも可能です。
#!/bin/bash
while getopts ':abc' opt; do
case "${opt}" in
a) echo "オプション -a を指定しました" ;;
b) echo "オプション -b を指定しました" ;;
c) echo "オプション -c を指定しました" ;;
?) echo "不正なオプション" >&2 ;;
esac
doneちなみに、echo の末尾の >&2 は、標準エラー出力への出力を意味しています(参考: echo の結果を標準エラー出力 (stderr) に出力する)。
引数ありのオプション
getopts では、次のような引数ありのオプションを扱うこともできます。
$ ./sample -b 100 -c 200
引数ありのオプションにしたいときは、オプション文字列の対象文字の後ろに : を付けます。
次の例では、-b オプションと -c オプションに引数を指定できるようにしています。
オプションに指定した引数の値は、$OPTARG 変数で参照できます。
#!/bin/bash
while getopts 'ab:c:' flag; do
case "${flag}" in
a) echo "オプション -a を指定しました" ;;
b) echo "オプション -b を指定しました(引数=${OPTARG})" ;;
c) echo "オプション -c を指定しました(引数=${OPTARG})" ;;
esac
done$ ./sample.sh -a -b 100
オプション -a を指定しました
オプション -b を指定しました(引数=100)
なお、引数ありのオプション(b: など)にした場合は、引数を指定しなかった場合はエラーになります。
$ ./sample.sh -b
./sample.sh: option requires an argument -- b
getopts の実践的な使用例
#!/bin/bash
usage() {
cat 1>&2 <<EOF
Usage: $(basename $0) [OPTIONS]
Options:
-h Display this message
-d DIR Output directory (default: .)
-v Use verbose output
EOF
exit -1
}
outdir='.'
verbose=''
while getopts ':d:vh' opt; do
case "${opt}" in
d) outdir="${OPTARG}" ;;
v) verbose='true' ;;
h) usage ;;
?) usage ;;
esac
done
if [ ! -z "$verbose" ]; then
echo "Verbose mode"
fi
echo Output directory is "${outdir}"$ ./sample.sh
Output directory is .
$ ./sample.sh -d out -v
Verbose mode
Output directory is out
$ ./sample.sh -h
Usage: sample.sh [OPTIONS]
Options:
-h Display this message
-d DIR Output directory (default: .)
-v Use verbose output