我一直在學習命令行參數解析。有長的絲這個了,我並不想在這裏挑起一個:
Using getopts in bash shell script to get long and short command line options
How do I parse command line arguments in Bash?
使用getopts的,如果你想分析的參數/值對,如「--opt值「,一種方法是讓getopts將其視爲名爲」 - 「的參數,並將該值變爲」-opt「。然後我們解析它,並通過符號${!OPTIND}
獲取用戶值。我需要更多地瞭解它。
在上面引用的第一個線程中,使用了${!OPTIND}
,有人說「那是什麼?」。答案是「其間接替代」。在閱讀關於間接參考資料的說明之後,尤其是https://unix.stackexchange.com/questions/41292/variable-substitution-with-an-exclamation-mark-in-bash和http://mywiki.wooledge.org/BashFAQ/006,我通常理解間接性,但我不明白${!OPTIND}
作爲它的一個例子。
$OPTIND
的值是一個整數,是下一個命令行參數的索引。這不是另一個數組中的值。
在上面的BashFAQ/006鏈接中,有關於間接性和一般性建議不使用它的警告。也許這沒什麼大不了的,但我希望儘可能避免危險。
我們可以避免間接嗎?似乎我應該能夠使用${OPTIND}
作爲一個整數取值從[email protected]
,[email protected][$OPTIND]}
。
如果你想要例子,這裏是一個腳本,我稱之爲「cli-6.sh」,它將接收長表單參數沒有等號。像這樣運行:
$ ./cli-6.sh -v --fred good --barney bad --wilma happy
離開-v以減少冗長。
$ ./cli-6.sh --fred good --barney bad --wilma happy
After Parsing values, ordinary getopts
VERBOSE 0
Arrays of opts and values
optary: fred barney wilma
valary: good bad happy
我們希望,這會運行你太:)我沒有使用關聯數組,因爲我希望這會在其他炮彈工作,最終保存的值。
#/usr/bin/env bash
die() {
printf '%s\n' "$1" >&2
exit 1
}
printparse(){
if [ ${VERBOSE} -gt 0 ]; then
printf 'Parse: %s%s%s\n' "$1" "$2" "$3" >&2;
fi
}
showme(){
if [ ${VERBOSE} -gt 0 ]; then
printf 'VERBOSE: %s\n' "$1" >&2;
fi
}
VERBOSE=0
## index for imported values in optary and valary arrays
idx=0
## Need v first so VERBOSE is set early
optspec=":vh-:"
while getopts "$optspec" OPTCHAR; do
case "${OPTCHAR}" in
-)
showme "OPTARG: ${OPTARG[*]}"
showme "OPTIND: ${OPTIND[*]}"
showme "OPTCHAR: ${OPTCHAR}"
showme "There is no equal sign in ${OPTARG}"
opt=${OPTARG}
val="${!OPTIND}"; OPTIND=$(($OPTIND + 1))
printparse "--${OPTARG}" " " "\"${val}\""
if [[ "$val" == -* ]]; then
die "ERROR: $opt value must be supplied"
fi
optary[${idx}]=${opt}
valary[${idx}]=${val}
idx=$(($idx + 1))
;;
h)
echo "usage: $0 [-v] [--anyOptYouQant[=]<valueIsRequired>] [--another[=]<value>]" >&2
exit 2
;;
v)
## if -v flag is present, it means TRUE
VERBOSE=1
;;
*)
if [ "$OPTERR" != 1 ] || [ "${optspec:0:1}" = ":" ]; then
die "Undefined argument: '-${OPTARG}'"
fi
;;
esac
done
echo "After Parsing values, ordinary getopts"
echo "VERBOSE $VERBOSE"
echo 'Arrays of opts and values'
echo "optary: ${optary[*]}"
echo "valary: ${valary[*]}"
因爲它是一個整數,所以它會引導你到一個位置參數$ 1,$ 2,... –
這似乎是一個非常不正當的手段,用getopts來解析長選項。我會使用['getopt'](http://manpages.ubuntu.com/manpages/xenial/en/man1/getopt.1.html)來代替([示例用法])(https://git.launchpad.net/~usd-import-team/ubuntu/+source/util-linux/tree/misc-utils/getopt-parse.bash)) –
getopt(來自util-linux)在某些平臺上不可用,所以我們選擇不依靠它。 – pauljohn32