私はgetopt / getoptsよりもシェルスクリプト引数を処理するためのよりきれいで「自己文書化」する方法を探しています。
それは提供する必要があります...
- 値の後に "=" または " " (空白) の有無にかかわらず長いオプションが完全にサポートされています。
- ハイフンで連結されたオプション名を正しく処理します(例:--ignore-case)。
- 引用符付きオプションの値を正しく処理します(例:--text "text string")。
getopt / getoptsに必要なケースステートメントに含まれる大きなループのオーバーヘッドを削除し、オプションの処理を次のように減らしたいと思います。
option=argumentparse "$@"
[[ option == "" ]] && helpShow
[[ option =~ -h|--help ]] && helpShow
[[ option =~ -v|--version ]] && versionShow
[[ option =~ -G|--GUI ]] && GUI=$TRUE
[[ option =~ --title ]] && TITLE=${option["--title"]}
ここで引数parse()関数は、さまざまな構文の可能性を一貫した形式、可能な連想配列に解析します。
どこかにエンコードされたものがあるでしょう。どんなアイデアがありますか?
(更新と名前変更)
ベストアンサー1
この質問は(少なくとも私にとっては)かなり多く見ましたが、答えが提出されていないので、採用された解決策を伝えます。
ノート
マルチインターフェイス出力関数などの一部の関数が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 "$@")"