Linux - Laços
Os laços permitem executar um conjunto de comandos repetidamente, dependendo de uma condição. Bash oferece os seguintes tipos de laços:
for
: executa um determinado número de vezeswhile
: executa enquanto a condição especificada for verdadeirauntil
: executa até que a condição especificada se torne verdadeira
Laço while
O laço while
executa enquanto uma condição for verdadeira e tem a seguinte sintaxe:
while condição do comandos_a_serem_executados done
Após o while
, vem a condição que será avaliada. Enquanto essa condição for verdadeira, o conjunto de comandos entre os operadores do
e done
será executado. Vamos considerar um exemplo simples:
#!/bin/bash # Script que utiliza o laço while num=0 while [ $num -lt 5 ] do echo "num é igual a $num" num=$((num+1)) done echo "Fim do programa" exit 0
Aqui, a condição é a seguinte expressão: [ $num -lt 5 ]
. Ou seja, a condição é verdadeira enquanto a variável num
for menor que 5 (por padrão, ela começa com valor 0). E enquanto essa condição for verdadeira, dois comandos são executados:
echo "num é igual a $num" num=$((num+1))
Isso significa que o valor da variável num
é exibido no console e seu valor é incrementado em 1. Dessa forma, o laço será executado 5 vezes. Ao executar o script:
programicio@Programicio:~$ bash hello num é igual a 0 num é igual a 1 num é igual a 2 num é igual a 3 num é igual a 4 Fim do programa
Laço until
O laço until
é semelhante ao while, mas possui ação inversa: ele executa o laço até que a condição se torne verdadeira. Por exemplo:
#!/bin/bash # Script que utiliza o laço until num=0 until [ $num -eq 5 ] do echo "num é igual a $num" num=$((num+1)) done echo "Fim do programa" exit 0
Aqui, os mesmos comandos do laço são usados, mas com uma condição diferente: $num -eq 5
, ou seja, verifica se a variável num
é igual a 5. Se for igual, o script termina sua execução.
O resultado do script será idêntico ao anterior:
programicio@Programicio:~$ bash hello num é igual a 0 num é igual a 1 num é igual a 2 num é igual a 3 num é igual a 4 Fim do programa
Laço for
O laço for
executa um conjunto de comandos um determinado número de vezes.
for (( contador; condição; incremento_do_contador)); do conjunto_de_comandos done
Após a palavra for
, entre parênteses duplos, temos o cabeçalho do laço, que consiste em três partes separadas por ponto e vírgula. A primeira parte define o contador. A segunda parte é a condição que, enquanto for verdadeira, o laço será executado. A terceira parte é o incremento ou alteração do contador.
Após o cabeçalho do laço, entre as palavras do
e done
, temos os comandos do laço.
Por exemplo, se precisamos executar uma ação 5 vezes, podemos definir o seguinte script:
#!/bin/bash # Script que utiliza o laço for for ((i=0; i < 5; i++)) do echo "i é igual a $i" done echo "Fim do programa" exit 0
Aqui, o contador é a variável i
, que começa com o valor 0.
A condição i < 5
é verdadeira enquanto a variável i
for menor que 5.
Após cada execução dos comandos do laço, o valor da variável i
é incrementado em 1
(i++
).
O corpo do laço é composto por um comando que exibe o valor da variável i
no console:
echo "i é igual a $i"
Dessa forma, antes de executar o laço, a variável i
é definida como 0. Em seguida, a condição i < 5
é verificada. Se i
for menor que 5, o comando echo i é igual a $i
é executado. Após a execução, o valor da variável i
é incrementado em 1 (i++
). Todo o processo se repete: a condição é verificada novamente e os comandos do laço são executados. Se a condição não for verdadeira: i
é igual ou maior que 5, o laço termina. Ao executar o script, obteremos o seguinte resultado:
programicio@Programicio:~$ bash hello i é igual a 0 i é igual a 1 i é igual a 2 i é igual a 3 i é igual a 4 Fim do programa
Para definir condições, podemos usar os operadores de comparação padrão: <
(menor que), >
(maior que), <=
(menor ou igual), >=
(maior ou igual), ==
(igual), !=
(diferente).
Para incrementar o contador do laço, podemos usar operadores de incremento (aumento de 1) ++
, decremento (diminuição de 1) --
, aumento com atribuição +=
, diminuição com atribuição -=
. Por exemplo, para aumentar o contador em 2:
for ((i=0; i < 5; i=i+2)) do echo "i é igual a $i" done
Outro exemplo é executar o laço até que o contador se torne igual a 0:
#!/bin/bash # Script que utiliza o laço for for ((i=10; i != 0; i--)) do echo "i é igual a $i" done echo "Fim do programa" exit 0
Laço for..in
Uma forma especial do laço for
, o for..in
, permite iterar sobre um conjunto de valores:
for variável in conjunto_de_valores do conjunto_de_comandos done
O laço for passa por um conjunto de valores, colocando cada valor na variável. Entre os comandos do
e done
são colocados os comandos que serão executados para cada valor do conjunto.
Por exemplo, podemos iterar sobre um arquivo de texto linha por linha:
#!/bin/bash for i in `cat /etc/passwd` do echo $i done exit 0
Neste exemplo, todas as linhas do arquivo /etc/passwd
são iteradas. Para obter as linhas, usamos o comando cat /etc/passwd
, que representa um conjunto de linhas. Cada linha é colocada na variável i
. Para cada linha, o comando echo $i
é executado.
Outro exemplo seria pingar alguns endereços da rede local. Para isso, definimos o seguinte script:
#!/bin/bash for i in $@ do ping -c 1 192.168.1.$i done exit 0
Observe o uso de $@
. Esse identificador permite acessar todos os argumentos fornecidos ao script na linha de comando, independentemente da quantidade. Usando o laço for, podemos iterar sobre cada um desses argumentos. Vamos executar o script passando um intervalo de endereços:
programicio@Programicio:~$ bash hello 1 2 3 4 5 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. --- 192.168.1.1 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data. --- 192.168.1.2 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms PING 192.168.1.3 (192.168.1.3) 56(84) bytes of data. --- 192.168.1.3 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms PING 192.168.1.4 (192.168.1.4) 56(84) bytes of data. --- 192.168.1.4 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms PING 192.168.1.5 (192.168.1.5) 56(84) bytes of data. 64 bytes from 192.168.1.5: icmp_seq=1 ttl=62 time=67.8 ms --- 192.168.1.5 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 67.823/67.823/67.823/0.000 ms
Nesse caso, o script recebe o conjunto 1 2 3 4 5
, e todo esse conjunto está disponível através de $@
. Durante a iteração no laço, cada número do conjunto é colocado na variável i
, que é usada para pingar o endereço.