usando 'case $ 1 in' para ler opções de comando - vários sinalizadores após traço e manipulando sinalizadores incomuns?

1

Estou fazendo um script bash que usa opções longas e sinalizadores curtos. Como eu quero opções longas, não posso usar getopts . Eu tentei usar o seguinte código:

while test -n "$1"; do
  case "$1" in
        -o|--override)  NO_CHANGE=yes;shift 1;;
        -r|--reset)     OV_RESET=yes;shift 1;;
        -h|--help)      hthemehelp;shift 1;;
        *)              break;;
  esac
done

Isso funciona quando eu o invoco como myscr -o -r ou myscr -h , mas quando tento myscr -or o programa apenas executa seu comportamento normal e executando myscr -or -h ele sai do loop antes de chegar a -h . A substituição de break por continue faz com que myscr -or e myscr -or -h sejam interrompidos.

    
por Ethan McTague 08.07.2014 / 19:19

2 respostas

1

Experimente o tamanho:

#!/bin/bash
pleasereset=1
while test -n "$1"; do
   pleaseshift=0
   [[ pleasereset -eq 1 ]] && thisvar=$1 && pleasereset=0;
   case "$thisvar" in
      -o*|--override) echo "override!"; pleaseshift=1;;
      -r*|--reset) echo "reset!"; pleaseshift=1;;
      -h*|--help) echo "help!"; pleaseshift=1;;
      *) break ;;
   esac
   if [[ "$pleaseshift" = "1" ]];
   then
      testvar=${thisvar##-}
      if [[ ${#testvar} -gt 1 ]] && [[ ! ${thisvar} = --* ]];
      then
         thisvar=-$( echo "$testvar" | cut -c 2- )
      else
         shift 1; pleasereset=1;
      fi
   fi
done

Observe que no primeiro parâmetro que não corresponde a nenhum caso específico, a análise de parâmetro será interrompida, portanto, ./foobar.sh -o --help -s -r não processará o -r . Isso pode ser ajustado alterando a linha *) break;; para o tratamento de erros, mas lembre-se de colocar o pleaseshift=1 !

    
por 09.07.2014 / 14:52
0

Talvez seja suficiente adicionar a linha desejada:

while test -n "$1"; do
  case "$1" in
        -or|-ro)        OV_RESET=yes;NO_CHANGE=yes;shift 1;;
        -o|--override)  NO_CHANGE=yes;shift 1;;
        -r|--reset)     OV_RESET=yes;shift 1;;
        -h|--help)      hthemehelp;shift 1;;
        *)              break;;
  esac
done

ou, mais complexo, você pode colocar o bloco case em uma função com shift 1 fora desse bloco, mas ainda dentro do tempo.
Para as opções dobradas ( -or , -oh , que não são das mais longas, você pode recursivamente chamar a mesma função para cada letra de case *) ... Você precisa de uma sinalização se você acabou de processar $1 como uma opção longa.Neste caso, no entanto, você expõe seu script tp mau comportamento devido ao erro de impressão (por exemplo, se eu escrever -overrider I will process -o -v -e -r -d '...)

    
por 09.07.2014 / 03:40