Execute a opção padrão quando nenhuma opção for especificada no getopts

4

Eu segui o tutorial aqui para aprender a usar getopts . Eu sou capaz de executar todas as opções corretamente fornecidas pelo usuário. Mas agora quero executar uma opção padrão quando nenhuma das opções é fornecida.

Por exemplo:

while getopts ":hr" opt; do
    case $opt in
        h )
            show_help;
            exit 1
            ;;
        r )
          echo "Default option executed"
          ;;
    esac
done

Portanto, se o usuário fornecer -h ou -r , os comandos correspondentes deverão ser executados (o que realmente acontece), mas quando nenhuma dessas opções for fornecida, -r deverá ser executado por padrão. Existe uma maneira de conseguir isso?

UPDATE

Eu tentei cas's sugestão e incluí *) na minha função getopts , mas nada parece estar acontecendo.

while getopts ":hr" opt; do
    case $opt in
        h )
            show_help;
            exit 1
            ;;
        r )
          echo "Default option executed"
          ;;

        \? )
          echo error "Invalid option: -$OPTARG" >&2
          exit 1
          ;;

        : )
          echo error "Option -$OPTARG requires an argument."
          exit 1
          ;;

        * )
          echo "Default option executed"
          ;;
    esac
done

Há algo de errado com esse trecho?

    
por Abhimanyu Saharan 02.06.2016 / 14:14

5 respostas

1

Adicionar uma opção padrão à instrução case não ajudará porque ela não será executada se getopts não tiver opções para analisar. Você pode ver quantas opções foram processadas com a variável OPTIND shell. De help getopts :

Each time it is invoked, getopts will place the next option in the
shell variable $name, initializing name if it does not exist, and
the index of the next argument to be processed into the shell
variable OPTIND.  OPTIND is initialized to 1 each time the shell or
a shell script is invoked.

Portanto, se OPTIND for 1, nenhuma opção foi processada. Adicione isto após o seu loop while :

if (( $OPTIND == 1 )); then
   echo "Default option"
fi
    
por 21.02.2018 / 17:40
0

O getopts do Bash sairá do loop while quando nenhuma opção for fornecida, configurando $ opt para '?'. Para determinar essa situação em um script, adicione uma cláusula if após o loop while , semelhante a:

if [ "$opt" = "?" ]
then
  echo "Default option executed (by default)"
fi

Para referência, consulte Bourne Shell Builtins

    
por 02.06.2016 / 14:33
0

Pelo que vejo, r não está esperando um argumento. Logicamente, não importa o que aconteça, r é executado da mesma maneira.

Eu tomaria o comando associado com r da cláusula getopts e executaria independentemente. Isso seria suficiente para suas necessidades, acredito. Em outras palavras, coloque a instrução echo após a instrução "done".

Você pode deixar r em getopts como um stub se desejar compatibilidade ou outros motivos.

Você também pode adicionar uma variável definida como zero como um comutador. Assim que qualquer opção diferente de r for selecionada, você terá uma linha que muda a variável para 1. Após a instrução done, você pode escrever "se a variável for igual a zero, executar o comando padrão".

Eu acho que gosto do Cas 'responder melhor. Eu queria comentar mas não tenho privilégios. Eu vou construir a ideia dele. Isto é o mesmo que Cas propôs, mas você só tem um comando (assim você não tem o mesmo comando e comete um erro no futuro), e ele lhe dará a possibilidade de usá-lo também - h.

DEF="Default command executed"
while getopts ":hr" opt;
   do case $opt in 
     h) show_help; 
        exit 1 ;; 
     r) echo "$DEF" ;; 
     *) echo "$DEF" ;; 
  esac
done
    
por 02.06.2016 / 14:19
0

Use o loop getopts para definir variáveis com base nos parâmetros que são passados. Em seguida, aja sobre essas variáveis:

#!/bin/sh

# Defaults:
do_help=0
do_r=0

while getopts "hr" opt; do
    case $opt in
        h) do_help=1 ;;
        r) do_r=1    ;;
        *) echo 'Error in command line parsing' >&2
           exit 1
    esac
done

if [ "$do_help" -eq 1 ]; then
    show_help
    exit
fi

printf 'Default option executed (r=%d)\n' "$do_r"

Optei por deixar o código sair com êxito se -h for usado (a menos que show_help falhe) em vez de com um status de saída diferente de zero (pedir ajuda não é um erro).

Executando:

$ sh script.sh -r
Default option executed (r=1)
$ sh script.sh
Default option executed (r=0)
$ sh script.sh -h
script.sh[24]: show_help: not found

Isso tem o benefício de separar o código de análise da linha de comando do restante da lógica do seu script.

Ele também permite que você faça verificações de integridade básicas após o loop, mantendo o loop de análise real curto e simples. Por exemplo:

# command line parsing loop above here

if [ "$do_help" -eq 1 ] && [ "$do_r" -eq 1 ]; then
    echo 'Options -h and -r are mutually exclusive' >&2
    exit 1
fi

# code that acts on user-supplied options below
    
por 30.05.2018 / 14:18
0

Você também pode usar vários argumentos:

if [ "$#" == 0 ]; then
  usage
  exit 1
fi

Mais informações aqui: link

    
por 13.12.2018 / 14:53