Usando o comando `select` para imprimir um menu no Bash

Estou tentando implementar um menu simples usando o select comando. O script (para fins de teste) é o seguinte:

#!/bin/bash echo "*******************" PS3="Select an option and press Enter: " options=("apache" "named" "sendmail") select opt in "${options[@]}" do case $opt in "apache") date ;; "named") echo "test" ;; "sendmail") echo "test 2" ;; *) echo "invalid option";; esac done echo "*********************" 

O script não está reconhecendo nenhuma entrada válida que forneço e sempre imprime a mensagem “opção inválida”. O que estou fazendo de errado neste script?

Comentários

  • Sua entrada é 1, 2 ou 3, certo?

Resposta

Seu menu mostrado por selecionar será semelhante a:

1) apache 2) named 3) sendmail Select an option and press Enter: 

Neste momento, você digita ” 1 “ou” 2 “ou” 3 “: você não digita a palavra.

Além disso, select fará um loop até ver um break comando, então você deseja este:

 case $opt in "apache") date break ;; "named") echo "test" break ;; "sendmail") echo "test 2" break ;; *) echo "invalid option";; esac 

Se você quiser permitir que o usuário insira o número ou a palavra, você poderia escrever isto:

select opt in "${options[@]}"; do case "$opt,$REPLY" in apache,*|*,apache) do_something; break ;; named,*|*,named) do_something; break ;; sendmail,*|*,sendmail) do_something; break ;; esac done 

A vírgula não tem nenhum significado sintático, ela está lá apenas para ser capaz de correspondência de padrões em $ REPLY variável (que é o que o usuário realmente digitou) ou a variável $ opt

Comentários

  • O select o comando precisa de um break, não case.
  • Obrigado! Não percebi que eram opções numéricas. Duhh!
  • Hah, eu também programo em C e, você precisa de um break lá em cada seção. No entanto, você nunca precisará de um break em um bloco case … esac em um shell script . Pode acontecer tão facilmente confundi-los. 🙂
  • @syntaxerror, você ' está certo, você não ' não precisa break para case. No entanto, você precisa de um break para escapar do select loop.
  • @glenn jackman Eu gostaria de ter isso se tornou um comentário mais útil (veja a seguir). Portanto, seria ótimo se você concordasse em excluir seu comentário de 12h55. Farei o mesmo com o meu, é claro.

Resposta

Seu $opt a variável será definida para a palavra de opção correspondente ao número que o usuário inserir. Se você quiser ver o que o usuário realmente digitou, consulte $REPLY.

Comentários

  • Considerando que case compara $opt com " apache ", " nomeado " e " sendmail ", está correto e nada precisa ser alterado.
  • @manatwork, a menos que o OP queira que o usuário digite as palavras " apache ", " nomeado " ou " sendmail " em vez de pressionar 1, 2 ou 3.
  • Interessante. $ REPLY detém 1 / 2 / 3 e $ opt detém apache / named / sendmail
  • @fred, sim, $REPLY é o que o usuário digitou e, se for um número válido, $opt será a palavra correspondente a esse número.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *