Skip to content

🐈 Nekonote.

Bashでちょっと凝ったオプションの解析をする

June 29, 2016

痒いところに手が届かないのをなんとかしたかったのねん


Bashスクリプトを書いてたら、ちょっと凝ったオプション解析をしたくなった。

  • ロングオプションも使えるようにしたい
  • オプションの第二引数は任意にしたい

Bashスクリプトでオプション解析といえば getopt や getopts を使うと思いますが、

  • getopt はBashのビルトインコマンドなのでどこでも使えるけどロングオプションが使えない
  • getopts は BSD系(macOSなど) と GNU系(Linuxなど) で動きが違う

など微妙に痒いところに手が届かないので、下記のQiita記事を参考に、メモがてらちょっとアレンジしつつオレオレオプション解析を書いてみました。

bash によるオプション解析

下記をパースに使えば

  • ロングオプションが使える
  • 任意のオプションごとの引数を使える
  • オプション外の値を処理できる

・・・ようになりました

#!/bin/bash
PROGNAME="$( basename $0 )"
# Usage
function usage() {
cat << EOS >&2
Usage: ${PROGNAME} [-h,--hoge] [--fuga [VALUE]] [--piyo VALUE]
A sample script of parsing on bash.
Options:
--hoge A single option.
--fuga A option with optional value.
--piyo A option with required value.
-h, --help Show usage.
EOS
exit 1
}
# オプションをパース
PARAM=()
for opt in "$@"; do
case "${opt}" in
'--hoge' )
# 通常のオプションの場合
HOGE=true; shift
;;
'--fuga' )
# オプションに続く値が 任意 の場合
FUGA=true; shift
if [[ -n "$1" ]] && [[ ! "$1" =~ ^-+ ]]; then
FUGA_VALUE="$1"; shift
fi
;;
'--piyo' )
# オプションに続く値が 必須 の場合
if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
echo "${PROGNAME}: option requires an argument -- $( echo $1 | sed 's/^-*//' )" 1>&2
exit 1
fi
PIYO=true
PIYO_VALUE="$2"
shift 2
;;
'-h' | '--help' )
usage
;;
'--' | '-' )
shift
PARAM+=( "$@" )
break
;;
-* )
echo "${PROGNAME}: illegal option -- '$( echo $1 | sed 's/^-*//' )'" 1>&2
exit 1
;;
* )
if [[ -n "$1" ]] && [[ ! "$1" =~ ^-+ ]]; then
PARAM+=( "$1" ); shift
fi
;;
esac
done
# オプション無しの値を使う場合はここで処理する
X_VALUE="${PARAM}"; PARAM=("${PARAM[@]:1}")
Y_VALUE="${PARAM}"; PARAM=("${PARAM[@]:1}")
Z_VALUE="${PARAM}"; PARAM=("${PARAM[@]:1}")
[[ -z "${X_VALUE}" ]] && usage
[[ -z "${Y_VALUE}" ]] && usage
[[ -z "${Z_VALUE}" ]] && usage
# 規定外のオプションがある場合にはusageを表示
if [[ -n "${PARAM[@]}" ]]; then
usage
fi
# 結果を表示
cat << EOS | column -t
HOGE ${HOGE:-false}
FUGA ${FUGA:-false}
FUGA_VALUE ${FUGA_VALUE}
PIYO ${PIYO:-false}
PIYO_VALUE ${PIYO_VALUE}
X_VALUE ${X_VALUE}
Y_VALUE ${Y_VALUE}
Z_VALUE ${Z_VALUE}
EOS

関連リンク


忘備録や調べたことなどを気が向いたときに書いたりします。