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 comando read ou o menu select: a variável REPLY.

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’

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Post comment