Aula 13 – O menu ‘select’
Aula 12 – Os loops ‘while’ e ‘until’ | Índice | Aula 14 – Estruturas de decisão ‘if’ e ‘case’
Seu apoio é muito importante para a criação e a manutenção dos cursos gratuitos do canal debxp:
13.1 – Um menu simplificado
O quarto tipo de loop que o Bash nos oferece combina a capacidade de percorrer os valores de uma lista alimentando uma variável (como no loop for
) com os loops infinitos que fizemos com o while
e o until
— trata-se do menu select
.
O select
é um loop especialmente criado para gerar menus. Na verdade, ele é tão especializado nisso, que tem até o seu próprio prompt no shell: o prompt PS3
.
13.2 – Sintaxe
Sua sintaxe geral é idêntica à do loop for
:
select NOME [in LISTA]; do
COMANDOS
done
Ou, numa linha…
select NOME [in LISTA]; do COMANDOS; done
Cada elemento da LISTA
será utilizado para a exibição de um menu numerado seguido de um prompt que espera pela opção do usuário.
Por exemplo:
:~$ select fruta in banana laranja abacate; do echo $fruta && break; done
1) banana
2) laranja
3) abacate
#? _
O valor padrão do prompt PS3
é #?
. Quando o usuário digita o número correspondente à sua opção, o valor da string correspondente ao número escolhido é atribuído à variável NOME
(fruta
, no exemplo), o bloco de comandos é executado e um novo ciclo é iniciado, a menos que um dos comandos do bloco encerre o loop (com um break
) ou a sessão do shell (com um exit
).
Se não houver nenhum valor no prompt quando o usuário teclar Enter, a lista de opções e o prompt serão exibidos novamente. Sem um comando de saída, cada escolha feita levará a uma nova exibição do prompt.
13.3 – O prompt ‘PS3’
O Bash trabalha com cinco prompts diferentes, cada um deles armazenado em uma variável de ambiente:
Variável | Descrição |
---|---|
PS0 | Contém um string que é expandida após a execução de um comando e exibida antes de qualquer saída do comando. |
PS1 |
É o prompt de comandos do terminal, por exemplo… :~$ |
PS2 |
Prompt de continuação, exibido no terminal quando o nosso comando está incompleto. Geralmente, seu valor é > . |
PS3 |
É o prompt do loop select e seu valor padrão é #? . |
PS4 |
Define o prefixo das saídas que estão sendo rastreadas em um script (por exemplo, quando utilizamos o parâmetro de execução set -x no script). Seu valor padrão geralmente é + . |
No caso, a variável que nos interessa é a PS3
, que pode ser definida antes da execução do loop select
. Observe no exemplo:
PS3="Escolha um número ou tecle '4' para sair: "
select fruta in banana laranja abacate sair; do
[[ $fruta = "sair" ]] && break
echo "Você escolheu $fruta."
break
done
Executando o script, esta seria a saída no terminal:
1) banana
2) laranja
3) abacate
4) sair
Escolha um número ou tecle '4' para sair:
Repare também que nós definimos dois pontos de saída para o loop: o primeiro, caso
o usuário escolha 4
, atribuindo sair
ao valor de fruta
, e o segundo após a execução
dos demais comandos do bloco.
Importante! A variável
NOME
recebe o valor da string associada ao número da lista, e não o número que foi digitado! Para obter o número digitado, nós utilizamos uma variável que o shell sempre gera após um comandoread
ou o menuselect
: a variávelREPLY
.
13.4 – Menus com ‘while’ e ‘until’
Mesmo tendo aplicações muito mais genéricas, os loops while
e until
são bastante utilizados na criação de menus. Na verdade, os menus com o loop select
, embora práticos em algumas situações, podem ser um pouco limitados, especialmente quando precisamos de um maior grau de comunicação com o usuário.
De forma geral, todo menu com while
ou until
seguirá essa estrutura:
fruta=(banana laranja abacate)
while true; do
clear
echo "1. Banana"
echo "2. Laranja"
echo "3. Abacate"
echo "4. Sair"
read -p "Escolha o número da sua opção: " opt
[[ $opt -eq 4 ]] && break
echo "Você escolheu ${fruta[$(($opt - 1))]}."
read -p "Tecle algo para continuar..." continua
done
Como o comando read
já nos oferece um prompt, o echo
das opções também poderia ser dispensado:
fruta=(banana laranja abacate)
while true; do
clear
read -p "
1. Banana
2. Laranja
3. Abacate
4. Sair
Escolha o número da sua opção: " opt
[[ $opt -eq 4 ]] && break
echo "Você escolheu ${fruta[$(($opt - 1))]}."
read -p "Tecle algo para continuar..." continua
done
Evidentemente, seria preciso tratar a entrada do usuário para garantir que ele só digitou números de 1 a 4, mas esse é o esquema geral de um menu. Basicamente, nós sempre teremos uma lista de opções, um prompt para a entrada da escolha, e um bloco de comandos onde a escolha do usuário será tratada e direcionada de alguma forma para uma ação correspondente.
É neste ponto que entram as estruturas de decisão do Bash, como as declarações case
e if
, por exemplo, que serão vistas na próxima aula.
Aula 12 – Os loops ‘while’ e ‘until’ | Índice | Aula 14 – Estruturas de decisão ‘if’ e ‘case’