Como lidar com o fim das opções - em getopts

7

Eu uso getopts para analisar argumentos em scripts bash como

while getopts ":hd:" opt; do
  case $opt in
    d ) echo "directory = $OPTARG"; mydir="$OPTARG"; shift $((OPTIND-1)); OPTIND=1 ;;
    h ) helptext
      graceful_exit ;;
    * ) usage
      clean_up
      exit 1
  esac
done

exeparams="$*"

exeparams conterá opções / argumentos não analisados. Desde que eu quero usar exeparams para manter opções para um comando a ser executado dentro do script (que pode se sobrepor com as próprias opções de scripts), eu quero usar - para terminar as opções passadas para o script. Se eu passar, por exemplo,

myscript -d myscriptparam -- -d internalparam

exeparams será retido

-- -d internalparam

Agora quero remover o -- inicial para passar esses argumentos para o comando interno. Existe uma maneira elegante de fazer isso ou posso obter uma string que contém apenas o restante sem -- de getopts?

    
por highsciguy 14.11.2012 / 23:10

2 respostas

6

Que tal:

# ... getopts processing ...

[[ $1 = "--" ]] && shift
exeparams=("$@")

Note que você deve usar uma matriz para manter os parâmetros. Isso manipulará adequadamente todos os argumentos que contiverem espaços em branco. Desreferencia o array com "${exeparams[@]}"

    
por 14.11.2012 / 23:36
13

Use o shift incorporado. Primeiro, faça o% normalgetopts para o seu script. Depois que esse loop for concluído,

shift "$((OPTIND - 1))"

mudará todas as opções já processadas.

A partir daí, você terá que concluir o processamento dos argumentos não opcionais, se houver, para a primeira parte do script (antes do -- ). Depois de encontrar o -- , altere-o até que somente a última parte permaneça (a parte -d internalparam que vem depois de -- ). Uma maneira de fazer isso (usando a sintaxe bash ):

while [[ $# -gt 0 ]]; do
    # process next argument
    case $1 in
    foo) # process foo
    ;;
    --) shift; break;; # found '--', discard it and exit loop
    *) # handle unrecognized argument
    ;;
    esac
    # not '--', so discard the argument and continue
    shift
done

Finalmente, apenas o segundo conjunto de opções / argumentos permanece, o qual você pode passar. Do NÃO use $* para passar os demais parâmetros para outro comando. Use "$@" , que preserva a divisão original de palavras.

external_command "$@"
    
por 14.11.2012 / 23:14

Tags