ここでは、util-linux版のgetoptコマンドを利用します。
getoptコマンドはシェルスクリプトの引数を渡す必要があります。
基本的に
1 |
getopt -o ショートオプション文字列 -l ロングオプション文字列 -- "$@" |
のような構文で利用できます。また、-nオプションでプログラム名を入れるとエラーメッセージでそのプログラム名を表示してくれます。
また、互換モードとして
1 |
getopt ショートオプション文字列 "$@" |
の構文で利用すると、コマンドの出力に引用符がつかなくなり、evalコマンドで引数をセットし直すときに問題が起きる可能性があります。
例えば、引用符がある例とない例は以下のようになります。
1 2 3 4 |
$ echo $(getopt -o 'a:bc' -- -a adata -b -c aa bb cc) -a 'adata' -b -c -- 'aa' 'bb' 'cc' $ echo $(getopt 'a:bc' -a adata -b -c aa bb cc) -a adata -b -c -- aa bb cc |
以下はgetoptコマンドを利用したオプション解析の例になります。
getopt_analyze.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
#!/bin/bash function main(){ local short_opt_str='ab:c::' local long_opt_str='aopt,bopt:,copt::' local progname='getopt_analyze.sh' local TEMP=$(getopt -o "$short_opt_str" -l "$long_opt_str" -n "$progname" -- "$@") if [ $? -ne 0 ]; then echo 'Error...' >&2 exit 1 fi # 引数の再設定 eval set -- "$TEMP" unset TEMP # オプションのデフォルト値の初期化 local -A table=() local -A datatable=() table+=([a]=false) table+=([b]=false) table+=([c]=false) datatable+=([b]=) datatable+=([c]=) # オプションの解析 while true; do case "$1" in '-a'|'--aopt') table[a]=true shift ;; '-b'|'--bopt') table[b]=true datatable[b]="$2" shift 2 ;; '-c'|'--copt') table[c]=true datatable[c]="$2" shift 2 ;; '--') shift break ;; *) echo 'Internal error' >&2 exit 1 ;; esac done # オプションの解析結果の処理 local optlist=(a b c) for opt in "${optlist[@]}"; do echo "$opt : ${table[$opt]}" if [[ "$opt" == 'c' && -z "${datatable[$opt]}" ]]; then echo "c option is no data" elif [[ -n "${datatable[$opt]}" ]]; then echo "$opt data: ${datatable[$opt]}" fi done while [ $# -gt 0 ]; do echo "PROGRAM_ARG: $1" shift done } main "$@" |
このプログラムの実行結果は以下のようになります。
実行結果
1 2 3 4 5 6 7 8 9 |
$ bash getopt_analyze.sh -a --bopt boptdata -c aa bb cc a : true b : true b data: boptdata c : true c option is no data PROGRAM_ARG: aa PROGRAM_ARG: bb PROGRAM_ARG: cc |
オプションの引数が任意だった場合の指定方法
また、'::'でオプションに引数をつけるかつけないかの任意にすることができます。
その場合のオプションの引数の指定方法は以下のような方法になります。
1 2 3 4 5 6 7 |
$ bash getopt_analyze.sh -c'coptdata' aa bb cc | grep '^c' c : true c data: coptdata $ $ bash getopt_analyze.sh --copt='coptdata' aa bb cc | grep '^c' c : true c data: coptdata |
ショートオプション形式ではオプションのすぐ後にオプションの引数をつけます。
ロングオプション形式では'='をつけて、オプションの引数をつけます。