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 umbreak
, nãocase
. - 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 umbreak
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
paracase
. No entanto, você precisa de umbreak
para escapar doselect
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émapache
/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.