Recentemente precisei manipular um pouco a entrada de dados em Bash Shell, obtendo o que o usuário digitar no console e fazendo alguns tratamentos. Em minhas pesquisas vi que o comando
read tem várias opções que ajudam nessa tarefa.
Estou há uns meses aprendendo aos poucos sobre shell e ainda não tinha visto muito material usando essas opções do read, talvez por não haver a necessidade, ou porque para aprender mais sobre ele não basta "man read", e sim consultar diretamente o manual do bash quem tem mais de 3 mil linhas.
Então resolvi escrever esse material para ajudar a mostrar como estender o read.
O uso padrão, quem escreve scripts em shell já conhece:
read VARIAVEL
Que segue uma sintaxe comum a outras linguagens (por exemplo a Pascal).
Então vamos ver algumas opções que estendem os poderes do read.
I/O (imprimindo e lendo valores) ao mesmo tempo
read -p 'TEXTO' VARIAVEL
A opção -p originalmente mostra uma mensagem na saída de erro padrão, se você não estiver redirecionando essa saída para o vácuo (/dev/null) ou para nenhum outro lugar, será apresentada na tela do console normalmente.
Exemplo:
#!/bin/bash
read -p "Digite seu email : " EMAIL
echo "$EMAIL" | egrep -q '\w+@\w+\.\w+'
# validando
[ "$?" -eq 0 ] && echo 'email aceito!' || echo -e '\033[31;1memail inválido\033[m'
Obs.: Não há quebra de linha após o uso do read -p.
Lendo diretamente para um array
read -a ARRAY
Os valores digitados, separados pelo caractere padrão espaço (definido em IFS), são atribuídos ao array informado, nesse caso ARRAY.
Exemplo:
#!/bin/bash
IFS=';' # alterando o separador padrão
read -a FRUTAS -p "Digite as frutas que você gosta (separadas por ';' ponto e virgula) : "
# verificando se algum favor foi fornecido
[ ! "${FRUTAS[0]}" ] && echo -e '\033[31;1mNenhum valor fornecido\033[m' && exit
echo "Primeira fruta informada: ${FRUTAS[0]}" # mostrando o primeiro item do array
echo "Quantidade de frutas informadas ${#FRUTAS[@]}" # mostrando a quantidade de valores do array
echo "Todas as frutas informadas: ${FRUTAS[@]}" # mostrando todos os elementos do array
Obs.: Se quisermos alterar o separador padrão basta modificar o conteúdo de IFS.
Encerrando a leitura ao digitar determinado caractere
read -d CHAR
Você pode usar a opção -d para informar um delimitador (terminador) para o read, sendo que ele será encerrado quando esse caractere for digitado, encerrando a leitura até o caractere anteriormente informado.
Exemplo:
#!/bin/bash
# A entrada de dados é encerrada ao digitar a interrogação '?'
read -p "Digite sua pergunta? : " -d'?' PERGUNTA
echo
echo "$PERGUNTA"
Você pode inclusive digitar ENTER e mesmo assim o read não será encerrado (CTRL+C é covardia, ele faz parte do bash e vai encerrar).