for com lista
A forma mais comum do for itera sobre uma lista de palavras:
for DISTRO in debian ubuntu fedora arch; do
echo "Distro: $DISTRO"
done
Distro: debian
Distro: ubuntu
Distro: fedora
Distro: arch
Você pode usar expansão de chaves ou a saída de um comando:
# Sequência numérica
for i in {1..5}; do
echo "Servidor srv-$i"
done
# Saída de comando
for USER in $(cut -d: -f1 /etc/passwd | head -3); do
echo "Usuário: $USER"
done
for estilo C
Para iterações numéricas com controle fino, use a sintaxe for ((;;)):
for ((i=0; i<5; i++)); do
echo "Passo $i"
done
Passo 0
Passo 1
Passo 2
Passo 3
Passo 4
while
O while executa enquanto a condição for verdadeira. Muito usado com read para processar arquivos linha a linha:
# Contar de 1 a 5
COUNT=1
while [[ $COUNT -le 5 ]]; do
echo "Contagem: $COUNT"
((COUNT++))
done
while read — processando arquivos
A forma idiomática de ler um arquivo no Bash:
while IFS=: read -r USER _ UID_ _; do
if [[ $UID_ -ge 1000 ]]; then
echo "Usuário humano: $USER (UID $UID_)"
fi
done < /etc/passwd
Usuário humano: joao (UID 1000)
Usuário humano: maria (UID 1001)
Dica: Use
IFS=: antes de read para mudar o delimitador sem afetar o resto do script. O -r impede que barras invertidas sejam interpretadas.until
O until é o inverso do while: executa até que a condição se torne verdadeira.
# Esperar um serviço subir
until systemctl is-active --quiet nginx; do
echo "Aguardando nginx..."
sleep 2
done
echo "nginx está ativo!"
break e continue
break sai do loop imediatamente. continue pula para a próxima iteração.
for FILE in /var/log/*.log; do
# Pular arquivos vazios
[[ ! -s "$FILE" ]] && continue
LINES=$(wc -l < "$FILE")
echo "$FILE: $LINES linhas"
# Parar após encontrar um arquivo com mais de 10000 linhas
[[ $LINES -gt 10000 ]] && break
done
Iterando sobre arquivos
Use glob patterns para iterar sobre arquivos de forma segura:
# Renomear todos os .txt para .bak
for FILE in /tmp/dados/*.txt; do
[[ -e "$FILE" ]] || continue # protege contra glob sem match
mv "$FILE" "${FILE%.txt}.bak"
echo "Renomeado: $FILE"
done
Dica: Nunca faça
for FILE in $(ls *.txt). Use glob direto: for FILE in *.txt. O ls quebra com espaços e caracteres especiais em nomes de arquivos.