hack のためのネタ帳, etc,,,

通常コマンドである getopt を使ったオプション解析の例

使用例

getopts_sample.sh

#!/usr/bin/env bash

function check_getopt ()
{
  which getopt &>/dev/null || { echo "Error: getopt is not found." >&2; exit 1; }
  local result=`getopt -T` errcode=$?
  [ $errcode -ne 4 ] && { echo "Error: getopt is not enhanced version." >&2; exit 1; }
}

check_getopt

OPTS=`getopt -o ab: --long alpha,bravo: -- "$@"` || { echo "Error: getopt failed" >&2;  exit 1; }
eval "set -- $OPTS"
while (( 0 < $# )); do
  case "$1" in
    -a|--alpha) echo "alpha: $1"        ; shift   ;;
    -b|--bravo) echo "bravo: $1 ${2@Q}" ; shift 2 ;;
    --) shift ; break ;;
    *) echo "Warning: unknown option: $1"; shift ;;
  esac
done
echo "ARGS[$#]: $@"

実行結果

$ ./getopt_sample.sh x -a -ab"p p" -b"q q" -b "r r" --bravo="s s" --bravo "t t" y
alpha: -a
alpha: -a
bravo: -b 'p p'
bravo: -b 'q q'
bravo: -b 'r r'
bravo: --bravo 's s'
bravo: --bravo 't t'
ARGS[2]: x y
bash 組み込みコマンドの getopts と違って、長いオプションも使えるし、option と positional が前後しても問題ない。
-abp みたいに複数のオプションをまとめられるのは getopts 同様だが、
長いオプションでも --bravo p とか --bravo=p のように = の有り無しを適当に記述出来るなど、
柔軟性が高い記述が出来る。

getopt と case .. esac とでオプションの定義を冗長に繰り返さないといけないことに加えて、
特にオプションが大量にある場合 getopt のところが凄く長くなってしまうのが面倒な点は getopts と同様。

以下で参考に挙げたページでは、空白や特殊文字厳禁みたいに書いてあったが、
少なくとも今時点の cygwin だと適当にクオーティングしてくれてるのようなので、
eval で set -- に渡しとけば問題なさそうだった。

man 見るとこれは enhanced version の機能なんだそうで、
compatible mode だと空白と特殊文字は正常に扱えないと明記してある。
getopt -T して、出力なしで error status 4 なら enhanced version
-- が出力されて error status 0 なら enhanced じゃない version らしい。
もっとも quoting に限らず getopt は環境依存が結構大きいようで、
例えば FreeBSD 6 の getopt は --long をはじめとして getopt 用のオプションすら一切ない状況。
という事で getopts よりも高機能な反面、環境依存に関する懸念が付きまといそうな雰囲気。
もういっそ getopt -T で error status 4 返ってこなかったらバッサリ切ったほうが良いんじゃないかって気がする。

参考

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Wiki内検索

フリーエリア

管理人/副管理人のみ編集できます