Bash
更簡單地處理 shell 腳本選項
我正在尋找處理 shell 腳本參數的方法,它比 getopt/getopts 更乾淨、更“自我記錄”。
它需要提供…
- 完全支持在 ‘=’ 或 ’ ‘(空格)之後帶或不帶值的長選項。
- 正確處理帶連字元的選項名稱(即 –ignore-case)
- 正確處理帶引號的選項值(即 –text “A text string”)
我想用 getopt/getopts 需要的嵌入式 case 語句消除大循環的成本,並將選項處理減少到類似…
option=argumentparse "$@" [[ option == "" ]] && helpShow [[ option =~ -h|--help ]] && helpShow [[ option =~ -v|--version ]] && versionShow [[ option =~ -G|--GUI ]] && GUI=$TRUE [[ option =~ --title ]] && TITLE=${option["--title"]}
在這裡,argumentparse() 函式將各種語法可能性解析為一致的格式,可能是關聯數組。
那裡一定有什麼編碼的東西。有任何想法嗎?
(更新並重命名)
由於這個問題已經被查看了這麼多(至少對我來說),但沒有送出答案,傳遞採用的解決方案……
注意
一些函式,如多介面輸出函式
ifHelpShow()
,uiShow()
在此處使用但不包括在內,因為它們的呼叫包含相關資訊,但它們的實現不包含相關資訊。############################################################################### # FUNCTIONS (bash 4.1.0) ############################################################################### function isOption () { # isOption "$@" # Return true (0) if argument has 1 or more leading hyphens. # Example: # isOption "$@" && ... # Note: # Cannot use ifHelpShow() here since cannot distinguish 'isOption --help' # from 'isOption "$@"' where first argument in "$@" is '--help' # Revised: # 20140117 docsalvage # # support both short and long options [[ "${1:0:1}" == "-" ]] && return 0 return 1 } function optionArg () { ifHelpShow "$1" 'optionArg --option "$@" Echo argument to option if any. Within "$@", option and argument may be separated by space or "=". Quoted strings are preserved. If no argument, nothing echoed. Return true (0) if option is in argument list, whether an option-argument supplied or not. Return false (1) if option not in argument list. See also option(). Examples: FILE=$(optionArg --file "$1") if $(optionArg -f "$@"); then ... optionArg --file "$@" && ... Revised: 20140117 docsalvage' && return # # --option to find (without '=argument' if any) local FINDOPT="$1"; shift local OPTION="" local ARG= local o= local re="^$FINDOPT=" # # echo "option start: FINDOPT=$FINDOPT, o=$o, OPTION=$OPTION, ARG=$ARG, @=$@" >&2 # # let "$@" split commandline, respecting quoted strings for o in "$@" do # echo "FINDOPT=$FINDOPT, o=$o, OPTION=$OPTION, ARG=$ARG" >&2 # echo " o=$o" >&2 # echo "re=$re" >&2 # # detect --option and handle --option=argument [[ $o =~ $re ]] && { OPTION=$FINDOPT; ARG="${o/$FINDOPT=/}"; break; } # # $OPTION will be non-null if --option was detected in last pass through loop [[ ! $OPTION ]] && [[ "$o" != $FINDOPT ]] && { continue; } # is a positional arg (no previous --option) [[ ! $OPTION ]] && [[ "$o" == $FINDOPT ]] && { OPTION="$o"; continue; } # is the arg to last --option [[ $OPTION ]] && isOption "$o" && { break; } # no more arguments [[ $OPTION ]] && ! isOption "$o" && { ARG="$o"; break; } # only allow 1 argument done # # echo "option final: FINDOPT=$FINDOPT, o=$o, OPTION=$OPTION, ARG=$ARG, @=$@" >&2 # # use '-n' to remove any blank lines echo -n "$ARG" [[ "$OPTION" == "$FINDOPT" ]] && return 0 return 1 } ############################################################################### # MAIN (bash 4.1.0) (excerpt of relevant lines) ############################################################################### # options [[ "$@" == "" ]] && { zimdialog --help ; exit 0; } [[ "$1" == "--help" ]] && { zimdialog --help ; exit 0; } [[ "$1" == "--version" ]] && { uiShow "version $VERSION\n"; exit 0; } # options with arguments TITLE="$(optionArg --title "$@")" TIP="$( optionArg --tip "$@")" FILE="$( optionArg --file "$@")"