Aula 12 – Loops ‘while’ e ‘until’

Aula 11 – O loop ‘for’ | Índice | Aula 13 – O menu ‘select’


Seu apoio é muito importante para a criação e a manutenção dos cursos gratuitos do canal debxp:


12.1 – Estruturas de repetição condicional

Na aula sobre o loop for, nós vimos uma estrutura que executava um bloco de comandos à medida em que percorria sequencialmente cada elemento de uma lista. Mas existem outros dois tipos de loop no Bash que, em vez de percorrer valores, irão testar determinadas condições para decidir se continuam executando um bloco de comandos ou não. São os loops while e until.

As palavras while e until significam “enquanto” e “até”, respectivamente. Portanto, fica fácil deduzir que os blocos de comandos desses loops continuarão sendo executados “enquanto” uma condição for verdadeira (while) ou “até” uma condição tornar-se verdadeira (until).

12.2 – Sintaxe

Toda sintaxe aplicável ao loop while também é aplicável ao loop until, o que muda é apenas a forma como cada um deles reage às condições.

# Lopp while...

while CONDIÇÃO; do
    COMANDOS
done

while CONDIÇÃO; do COMANDOS; done

# Loop until...

until CONDIÇÃO; do
    COMANDOS
done

until CONDIÇÃO; do COMANDOS; done

Importante! A CONDIÇÃO não precisa ser necessariamente um comando test. Na
verdade, qualquer expressão que retorne um estado 0 (sucesso/verdadeiro) ou 1 (erro/falso) pode ser utilizada, inclusive os comandos internos true, false e o comando nulo :.

12.3 – O loop ‘while’

Como dissemos, o loop while executa repetidamente um bloco de comandos enquanto uma determinada condição for verdadeira:

n=0
while [[ $n -lt 5 ]]; do
    echo $n
    ((n++))
done

Neste caso, nós definimos o valor inicial de n fora do bloco de comandos. A cada ciclo nós verificamos se o seu valor ainda é menor do que 5, incrementando o valor original em +1 em seguida. Quando o valor de n, depois de ser incrementado, passar a ser igual a 5, o teste sairá com status 1 (falso), encerrando o loop. Sendo assim, cada um dos comandos no bloco é executado 5 vezes, resultando nesta saída no terminal:

0
1
2
3
4

Importante! Os comandos sempre serão executados durante os ciclos, e não ao final de todos os ciclos. O que delimita o bloco de comandos é a estrutura do COMANDOS; done.

12.4 – O loop ‘until’

O loop until segue a lógica inversa do loop while. Para que um ciclo seja executado, o teste tem que sair com status 1 (falso), e o loop será interrompido assim que o teste sair com status 0 (verdadeiro).

Por exemplo, para obter o mesmo resultado do exemplo anterior…

n=0
until [[ $n -eq 5 ]]; do
    echo $n
    ((n++))
done

Repare que, já no início, o teste sairia com status 1 (falso), e esta é a condição lógica que o loop until espera para liberar a execução do bloco de comandos. À medida em que o valor de n é incrementado, eventualmente ele será igual a 5, fazendo com que o teste retorne status 0 (verdadeiro) e os clicos sejam interrompidos.

A saída no terminal seria a mesma:

0
1
2
3
4

12.5 – Loops infinitos

Muitas vezes, existe a necessidade de executar loops indefinidamente, deixando por conta de alguma interferência do usuário ou de um teste no bloco de comandos a sua interrupção. Nesses casos, em vez de uma expressão a ser avaliada, nós utilizamos comandos internos que retornam imediatamente um estado de saída:

Comando Descrição
true Retorna sempre o status 0 (sucesso)
false Retorna sempre o status 1 (erro)
: Comando nulo, não faz nada e sempre retorna 0 (sucesso)

A interrupção de um loop infinito pode ser feita através de alguma intervenção do usuário, seja através do comando Ctrl+C no terminal, da espera pela entrada de um valor de um comando read, ou através de instruções que resultem na chamada dos comandos break ou exit.

Exemplo 1: loop while infinito…

while true; do
    COMANDOS
done

Ou ainda…

while : ; do
    COMANDOS
done

Exemplo 2: loop until infinito…

until false; do
    COMANDOS
done

12.6 – Interrompendo loops infinitos

Não existe uma fórmula definitiva para interromper um loop infinito pelo código, mas nós podemos entender o conceito geral analisando alguns exemplos. Aqui, nós utilizaremos apenas o loop while, mas, como se trata de um loop infinito, pouco importa se vamos utilizar a lógica until false ou while true, pois é o que acontece no bloco de comandos que nos interessa.

Exemplo1: utilizando o comando break

n=1
while true; do
  [[ $n -lt 5 ]] && echo "Ciclo $n" || break
  ((n++))
done

Como no primeiro exemplo, nós atribuímos o valor 5 à variável n. Só que, agora, o teste é feito no bloco de comandos, e não na declaração do while. Se o valor de n for maior do que 5, o teste retornará erro (1) e o comando break será executado, interrompendo a execução do loop.

Exemplo 2: controlando o loop com o comando read

while true; do
  read -p "Digite qualquer coisa ou Q para sair: " str
  [[ "$str" = [qQ] ]] && echo Saindo... && break \
                      || echo "Você digitou $str"
done

Desta vez, o comando read irá pausar o ciclo até o usuário entrar com algum texto. O texto digitado será armazenado na variável str e testado para ver se corresponde ao padrão q ou Q. Se isso acontecer, o loop será interrompido. Este é um método muito utilizado na construção de menus, assunto da nossa próxima aula.


Aula 11 – O loop ‘for’ | Índice | Aula 13 – O menu ‘select’

Deixe um comentário

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

Post comment