Bashでちょっと凝ったオプションの解析をする
痒いところに手が届かないのをなんとかしたかったのねん
Bashスクリプトを書いてたら、ちょっと凝ったオプション解析をしたくなった。
- ロングオプションも使えるようにしたい
- オプションの第二引数は任意にしたい
Bashスクリプトでオプション解析といえば getopt や getopts を使うと思いますが、
など微妙に痒いところに手が届かないので、下記のQiita記事を参考に、メモがてらちょっとアレンジしつつオレオレオプション解析を書いてみました。 qiita.com
下記をパースに使えば
- ロングオプションが使える
- 任意のオプションごとの引数を使える
- オプション外の値を処理できる
・・・ようになりました
#!/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