Lendo entrada do usuário
Esta aula ensina como ler entrada do usuário em scripts Bash usando o comando read. Você aprenderá a usar a opção -p para prompts, ler múltiplas variáveis e integrar read em loops para processamento interativo.
Em scripts Bash, a interação com o usuário é fundamental para criar ferramentas dinâmicas e adaptáveis. O comando read é a principal forma de capturar entrada do teclado, permitindo que o script reaja a dados fornecidos em tempo de execução. Nesta aula, exploraremos desde o uso básico até técnicas avançadas como prompts personalizados, leitura de múltiplos valores e integração com loops para processamento contínuo.
Dominar read é essencial para criar scripts que solicitam confirmações, coletam parâmetros ou implementam menus interativos. Veremos cada variação com exemplos práticos e boas práticas para evitar armadilhas comuns.
read
O comando read lê uma linha da entrada padrão (geralmente o teclado) e armazena o conteúdo em uma ou mais variáveis. Por padrão, ele lê até encontrar uma quebra de linha (Enter) e divide a linha em palavras usando os caracteres do IFS (Internal Field Separator), que por padrão são espaço, tabulação e nova linha.
Sintaxe básica: read nome_variavel. Se nenhuma variável for fornecida, o conteúdo é armazenado na variável especial REPLY. Exemplo simples:
#!/bin/bash
echo "Digite seu nome:"
read nome
echo "Olá, $nome!"
Quando o script executa, ele aguarda o usuário digitar algo e pressionar Enter. O texto digitado é atribuído à variável nome. É importante notar que read preserva espaços internos se a linha não for dividida por IFS, mas para linhas completas sem divisão, use read -r para evitar interpretação de barras invertidas.
Prompt (-p)
A opção -p permite exibir um prompt diretamente, eliminando a necessidade de um echo separado. O texto do prompt é exibido antes da leitura, e o cursor aguarda a entrada na mesma linha (a menos que o prompt inclua uma quebra de linha). Exemplo:
read -p "Digite sua idade: " idade
echo "Você tem $idade anos."
O prompt é exibido exatamente como fornecido. Para incluir uma nova linha, use \n dentro de aspas duplas (com echo -e ou diretamente no prompt com $'...'). Exemplo com várias linhas:
read -p $'Digite seu nome:\n> ' nome
echo "Nome: $nome"
Isso exibe "Digite seu nome:" em uma linha e "> " na próxima, aguardando a entrada. O uso de -p torna o código mais conciso e legível.
Múltiplas variáveis
O comando read pode atribuir palavras a múltiplas variáveis em uma única chamada. A linha de entrada é dividida de acordo com o IFS, e cada palavra é atribuída às variáveis na ordem. Se houver mais palavras que variáveis, o excedente vai para a última variável. Se houver menos, as variáveis restantes ficam vazias.
read -p "Digite seu nome, idade e cidade: " nome idade cidade
echo "Nome: $nome"
echo "Idade: $idade"
echo "Cidade: $cidade"
Se o usuário digitar "João 30 São Paulo", as variáveis recebem os valores corretos. Se digitar "Maria 25", cidade fica vazia. Se digitar "Pedro 40 Rio de Janeiro", cidade recebe "Rio de Janeiro" (o restante). Para capturar a linha inteira em uma variável, use apenas uma variável ou utilize IFS= para desabilitar a divisão.
Exemplo com IFS personalizado (por exemplo, lendo dados separados por vírgula):
IFS=',' read -p "Digite nome,idade: " nome idade
echo "Nome: $nome, Idade: $idade"
Isso permite processar entradas formatadas de forma flexível.
read em loop
Combinar read com loops é uma técnica poderosa para processar múltiplas entradas ou criar menus interativos. O padrão mais comum é usar while read para ler linhas de um arquivo ou da entrada padrão até EOF. Exemplo lendo de um arquivo:
while read linha; do
echo "Linha: $linha"
done < arquivo.txt
Para um loop interativo que pergunta repetidamente até que o usuário forneça uma resposta específica:
#!/bin/bash
while true; do
read -p "Deseja continuar? (s/n): " resposta
if [[ "$resposta" == "s" ]]; then
echo "Continuando..."
# faça algo
elif [[ "$resposta" == "n" ]]; then
echo "Saindo."
break
else
echo "Resposta inválida. Digite s ou n."
fi
done
Outra variação é usar for com uma lista de prompts, mas o while com read é mais flexível para entradas variáveis. Cuidado com loops infinitos: sempre forneça uma condição de saída.
Exemplo de menu com case:
#!/bin/bash
while true; do
echo "Menu:"
echo "1. Opção 1"
echo "2. Opção 2"
echo "3. Sair"
read -p "Escolha: " opcao
case $opcao in
1) echo "Você escolheu opção 1" ;;
2) echo "Você escolheu opção 2" ;;
3) echo "Saindo..."; break ;;
*) echo "Opção inválida" ;;
esac
done
Boas práticas
- Sempre use
-rcomreadpara evitar que barras invertidas sejam interpretadas como escapes, a menos que você queira esse comportamento. - Valide a entrada do usuário sempre que possível (por exemplo, verificar se é um número).
- Para senhas, use
read -spara não exibir o que é digitado. - Limpe o buffer de entrada se necessário (por exemplo, após um loop com leitura mista).
- Use
IFS= read -rpara ler linhas exatas sem divisão nem interpretação.
Referências
- GNU Bash Manual: read builtin
- Bash Beginners Guide: read command
- ShellCheck: read without -r
- Bash FAQ: How to read a file line-by-line?
- GNU Bash Manual: Parameter Expansion
- Advanced Bash-Scripting Guide: Chapter 10. Input/Output
Exercícios
-
Escreva um script que pergunte o nome do usuário e exiba uma saudação personalizada. Use
read -p.✓ Resposta:#!/bin/bash read -p "Digite seu nome: " nome echo "Olá, $nome! Seja bem-vindo(a)." -
Crie um script que leia três números (separados por espaço) e calcule a soma. Use múltiplas variáveis.
✓ Resposta:
#!/bin/bash read -p "Digite três números separados por espaço: " a b c soma=$((a + b + c)) echo "A soma é $soma" -
Escreva um script que leia linhas de um arquivo (fornecido como argumento) e exiba cada linha numerada. Use
while read.✓ Resposta:#!/bin/bash if [[ -f "$1" ]]; then contador=1 while IFS= read -r linha; do echo "$contador: $linha" ((contador++)) done < "$1" else echo "Arquivo não encontrado." fi -
Crie um script de menu que apresente as opções: 1 - Data, 2 - Hora, 3 - Sair. Use
readem loop comcase.✓ Resposta:#!/bin/bash while true; do echo "" echo "Menu:" echo "1 - Exibir data atual" echo "2 - Exibir hora atual" echo "3 - Sair" read -p "Escolha uma opção: " opcao case $opcao in 1) echo "Data: $(date +%d/%m/%Y)" ;; 2) echo "Hora: $(date +%H:%M:%S)" ;; 3) echo "Saindo..."; break ;; *) echo "Opção inválida. Tente novamente." ;; esac done -
Faça um script que peça ao usuário para digitar uma senha (sem eco) e confirme a senha em seguida. Se forem iguais, exiba "Senha confirmada", senão "Senhas não conferem". Use
read -s.✓ Resposta:#!/bin/bash read -sp "Digite a senha: " senha1 echo "" read -sp "Confirme a senha: " senha2 echo "" if [[ "$senha1" == "$senha2" ]]; then echo "Senha confirmada." else echo "Senhas não conferem." fi