Processamento mais simples de opções de script de shell

2

Estou procurando uma maneira de processar argumentos de script de shell que sejam mais limpos e mais "auto documentáveis" do que getopt / getopts.

Ele precisaria fornecer ...

  • Suporte total de opções longas com ou sem um valor depois de '=' ou '' (espaço).
  • Manuseio adequado de nomes de opções com hífen (por exemplo, --ignore-case)
  • Manuseio adequado dos valores das opções citadas (por exemplo, --text "Uma string de texto")

Eu gostaria de eliminar a sobrecarga do grande loop com a instrução case incorporada que o getopt / getopts requer e reduzir o processamento de opções para algo como ...

option=argumentparse "$@"
[[ option == ""           ]] && helpShow
[[ option =~ -h|--help    ]] && helpShow
[[ option =~ -v|--version ]] && versionShow
[[ option =~ -G|--GUI     ]] && GUI=$TRUE
[[ option =~ --title      ]] && TITLE=${option["--title"]}

Aqui, uma função argumentparse () resolve as várias possibilidades de sintaxe em um formato consistente, talvez um array associativo.

Deve haver algo codificado em algum lugar. Alguma idéia?

(atualizado e com novo título)

    
por DocSalvager 18.02.2013 / 10:06

1 resposta

0

Desde que esta pergunta foi vista tanto (para mim pelo menos) mas nenhuma resposta foi submetida, passando a solução adotada…

OBSERVAÇÃO
    Algumas funções, como as funções de saída multi-interface ifHelpShow() e uiShow() são usadas, mas não incluídas aqui, pois suas chamadas contêm informações relevantes, mas suas implementações não.

###############################################################################
# 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   "$@")"
    
por 17.01.2014 / 12:07