現在作成中のツールには次のコードがあります。
while [ $# -gt 0 ]; do
case "$1" in
--var1=*)
var1="${1#*=}"
;;
--var2=*)
var1="${1#*=}"
;;
--var3=*)
var1="${1#*=}"
;;
*)
printf "***************************\n
* Error: Invalid argument.*\n
***************************\n"
esac
shift
done
追加するオプションはたくさんありますが、そのうちの5つは配列として保存する必要があります。したがって、シェルからツールを呼び出すと、次のコマンドを使用できます。
./tool --var1="2" --var1="3" --var1="4" --var1="5" --var2="6" --var3="7"
値をvar1
配列として保存するには?それは可能ですか?もしそうなら、アレイが多すぎる場合、効率の面でアレイを処理する最良の方法は何ですか?
ベストアンサー1
Linuxを使用している場合(ユーティリティがインストールされているか、util-linux
または)、次のことができます。getopt
busybox
declare -A opt_spec
var1=() var2=() var4=false
unset var3
opt_spec=(
[opt1:]='var1()' # opt with argument, array variable
[opt2:]='var2()' # ditto
[opt3:]='var3' # opt with argument, scalar variable
[opt4]='var4' # boolean opt without argument
)
parsed_opts=$(
IFS=,
getopt -o + -l "${!opt_spec[*]}" -- "$@"
) || exit
eval "set -- $parsed_opts"
while [ "$#" -gt 0 ]; do
o=$1; shift
case $o in
(--) break;;
(--*)
o=${o#--}
if ((${opt_spec[$o]+1})); then # opt without argument
eval "${opt_spec[$o]}=true"
else
o=$o:
case "${opt_spec[$o]}" in
(*'()') eval "${opt_spec[$o]%??}+=(\"\$1\")";;
(*) eval "${opt_spec[$o]}=\$1"
esac
shift
fi
esac
done
echo "var1: ${var1[@]}"
この方法でスクリプトを呼び出すことができます。
my-script --opt1=foo --opt2 bar --opt4 -- whatever
--
getopt は構文解析、処理、および省略形の操作を代わりに実行します。
$opt_spec
あるいは、連想配列定義で変数を指定する代わりに、変数型を使用することもできます。
declare -A opt_spec
var1=() var2=() var4=false
unset var3
opt_spec=(
[opt1:]=var1 # opt with argument
[opt2:]=var2 # ditto
[opt3:]=var3 # ditto
[opt4]=var4 # boolean opt without argument
)
parsed_opts=$(
IFS=,
getopt -o + -l "${!opt_spec[*]}" -- "$@"
) || exit
eval "set -- $parsed_opts"
while [ "$#" -gt 0 ]; do
o=$1; shift
case $o in
(--) break;;
(--*)
o=${o#--}
if ((${opt_spec[$o]+1})); then # opt without argument
eval "${opt_spec[$o]}=true"
else
o=$o:
case $(declare -p "${opt_spec[$o]}" 2> /dev/null) in
("declare -a"*) eval "${opt_spec[$o]}+=(\"\$1\")";;
(*) eval "${opt_spec[$o]}=\$1"
esac
shift
fi
esac
done
echo "var1: ${var1[@]}"
次の短いオプションを追加できます。
declare -A long_opt_spec short_opt_spec
var1=() var2=() var4=false
unset var3
long_opt_spec=(
[opt1:]=var1 # opt with argument
[opt2:]=var2 # ditto
[opt3:]=var3 # ditto
[opt4]=var4 # boolean opt without argument
)
short_opt_spec=(
[a:]=var1
[b:]=var2
[c]=var3
[d]=var4
)
parsed_opts=$(
IFS=; short_opts="${!short_opt_spec[*]}"
IFS=,
getopt -o "+$short_opts" -l "${!long_opt_spec[*]}" -- "$@"
) || exit
eval "set -- $parsed_opts"
while [ "$#" -gt 0 ]; do
o=$1; shift
case $o in
(--) break;;
(--*)
o=${o#--}
if ((${long_opt_spec[$o]+1})); then # opt without argument
eval "${long_opt_spec[$o]}=true"
else
o=$o:
case $(declare -p "${long_opt_spec[$o]}" 2> /dev/null) in
("declare -a"*) eval "${long_opt_spec[$o]}+=(\"\$1\")";;
(*) eval "${long_opt_spec[$o]}=\$1"
esac
shift
fi;;
(-*)
o=${o#-}
if ((${short_opt_spec[$o]+1})); then # opt without argument
eval "${short_opt_spec[$o]}=true"
else
o=$o:
case $(declare -p "${short_opt_spec[$o]}" 2> /dev/null) in
("declare -a"*) eval "${short_opt_spec[$o]}+=(\"\$1\")";;
(*) eval "${short_opt_spec[$o]}=\$1"
esac
shift
fi
esac
done
echo "var1: ${var1[@]}"