Created
May 15, 2012 10:31
-
-
Save momo-lab/2700678 to your computer and use it in GitHub Desktop.
オプションの説明文(ヘルプ)内容から、オプションの解析を行うbash用スクリプト
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# コマンドの説明(ヘルプ)の文章をそれなりに解釈して、 | |
# 引数のオプション解析を行うbash用関数 | |
# | |
# 詳しくは後ろの方にある使用例を参照のこと。 | |
function optparse() { | |
if [[ ! $optparse_prefix ]]; then | |
optparse_prefix="opt_" | |
fi | |
function parse_message() { | |
echo "$optparse_help_message" | awk ' | |
function make_name(short, long) { | |
name = length(long) == 0 ? short : long; | |
gsub(/^--?/, "", name); | |
gsub(/-/, "_", name); | |
return name; | |
} | |
function parse(short, long, arg) { | |
# 長いパラメータに=を含むなら、それを引数とする | |
if (pos = match(long, /=/)) { | |
arg = "<" substr(long, pos + 1) ">"; | |
long = substr(long, 1, pos - 1); | |
} | |
# 引数をとるかどうか | |
is_arg = match(arg, /^<.*>$/); | |
# 変数として出力 | |
name = make_name(short, long); | |
print "optparse_args=(${optparse_args[@]} \"" name "|" short "|" long "|" is_arg "\")"; | |
# getopt用の引数を生成 | |
gsub(/^-/, "", short); | |
gsub(/^--/, "", long); | |
if (length(short) > 0) { | |
short_arg = short_arg short; | |
if (is_arg) short_arg = short_arg ":" | |
} | |
if (length(long) > 0) { | |
long_arg = long_arg "," long; | |
if (is_arg) long_arg = long_arg ":" | |
} | |
} | |
# 長短両方のパラメータ定義あり | |
/^[ \t]*-[^- ][, \t][ \t]*--[^ ]+/ { | |
gsub(/,$/, "", $1); | |
parse($1, $2, $3); | |
next; | |
} | |
# 短いパラメータ定義のみ | |
/^[ \t]*-[^- ][ \t]/ { | |
parse($1, "", $2); | |
next; | |
} | |
# 長いパラメータ定義のみ | |
/^[ \t]*--[^ ]+/ { | |
parse("", $1, $2); | |
next; | |
} | |
END { | |
print "optparse_short=" short_arg | |
print "optparse_long=" long_arg | |
} | |
' - | |
} | |
eval `parse_message` | |
args=`getopt -o +$optparse_short -l $optparse_long -- "$@"` | |
result=$? | |
if [[ $result != 0 ]]; then | |
echo "optparse_result=$result" | |
return $result | |
fi | |
eval set -- "$args" | |
until [[ "$1" == "--" ]]; do | |
for param in ${optparse_args[@]}; do | |
name=`echo $param | cut -d"|" -f1` | |
short=`echo $param | cut -d"|" -f2` | |
long=`echo $param | cut -d"|" -f3` | |
is_arg=`echo $param | cut -d"|" -f4` | |
if [[ "$1" == "$short" || "$1" == "$long" ]]; then | |
if [[ "$is_arg" == "1" ]]; then | |
echo "$optparse_prefix$name=\"$2\"" | |
shift | |
else | |
echo "$optparse_prefix$name=1" | |
fi | |
break | |
fi | |
done | |
shift | |
done | |
shift | |
set_param="" | |
while [[ $1 ]]; do | |
set_param="$set_param \"$1\"" | |
shift | |
done | |
echo "set -- $set_param" | |
echo "optparse_result=0" | |
return 0 | |
} | |
# 以降は使用例 | |
# 解析結果が代入される変数のプレフィクス | |
# 省略可能で、省略時は「opt_」となる | |
optparse_prefix="opt_" | |
# $optparse_help_message変数に、コマンドのヘルプ内容を記載する。 | |
# サポート可能なパターンを以下に示している | |
optparse_help_message=$(cat << EOL | |
usage: $0 [options] ... | |
-a 短いオプション(on/off) | |
-b <param> 短いオプション(パラメータ指定有り) | |
--long-c 長いオプション(on/off) | |
--long-d <param> 長いオプション(パラメータ指定有り) | |
--long-e=param 長いオプション(パラメータ指定有り) | |
-f, --long-f 長短両方のオプション(on/off) | |
-g, --long-g <param> 長短両方のオプション(パラメータ指定有) | |
-h, --long-h=param 長短両方のオプション(パラメータ指定有) | |
EOL | |
) | |
# optparse関数に引数を渡し、結果の標準出力をevalにかけることで、 | |
# 引数の解析結果を変数に代入する。 | |
eval "$(optparse "$@")" | |
# 解析に成功したかどうかは、$optparse_result変数でハンドリング可能 | |
if [[ $optparse_result != 0 ]]; then | |
echo "$optparse_help_message" | |
exit 1 | |
fi | |
# 実際の解析結果は$optparse_prefix変数で定義した文字列で始まる変数に代入される。 | |
# 長いオプションが定義されている場合は、長いオプション名(ハイフンはアンダースコアに変換)を | |
# 変数名とし、短いオプションの身が定義されている場合はそれを変数名とする。 | |
echo "-a=$opt_a" | |
echo "-b=$opt_b" | |
echo "--long-c=$opt_long_c" | |
echo "--long-d=$opt_long_d" | |
echo "--long-e=$opt_long_e" | |
echo "-f,--long-f=$opt_long_f" | |
echo "-g,--long-g=$opt_long_g" | |
echo "-h,--long-h=$opt_long_h" | |
# 解析できた引数は、$@からは取り除かれている。 | |
for i in `seq 1 $#`; do | |
echo "args[$i]=$1" | |
shift | |
done | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment