Bash Script – Usos do comando read
O comando “read” é um comando muito importante, quando pretendemos criar scripts BASH mais elaborados.
Neste artigo vou descrever algumas formas, de usar este comando em scripts BASH, para podermos tirar partido dele na elaboração de scripts.
O comando está preparado para ler dados por defeito do “stdin” (aquilo que escrevemos no terminal). No entanto podemos usa lo para ler outros ficheiros, bem como de variáveis.
Por defeito o comando escreve o que lê para o “stdout” (para o terminal). No entanto com parâmetros corretos podemos guardar o que foi lido em variáveis, arrays, para que possamos usa los no script.
Nos exemplos com ficheiros apenas a primeira linha é lida. Pois era necessário loops, para ler todas as linhas de um ficheiro, linha a linha. Mas como ainda não escrevi sobre os loops em bash, não serão usados nos exemplos.
O comando retorna sempre zero quando tudo corre bem.
Opções
A seguinte tabela, mostra nos as opções que temos para usar com o comando “read”.
Estas opções, devem ser usadas de acordo com as nossas necessidades, a fim de obter os resultados pretendidos em cada situação.
-a ARRAY | atribui as palavras lidas a índices sequenciais da variável array ARRAY, iniciando em zero |
-d DELIM | continua até o primeiro caractere de DELIM ser lido, ao invés de nova linha |
-e | usa Readline para obter a linha em um shell interativo |
-i TEXTO | usa TEXTO como o texto inicial para Readline |
-n NCHARS | retorna após ler NCHARS caracteres, ao invés de esperar por uma nova linha, mas respeita um delimitador se número de caracteres menor que NCHARS sejam lidos antes do delimitador |
-N NCHARS | retorna apenas após ler exatamente NCHARS caracteres, a menos que EOF (fim do arquivo) seja encontrado ou `read’ esgote o tempo limite, ignorando qualquer delimitador |
-p CONFIRMAR | mostra a string PROMPT sem remover nova linha antes de tentar ler |
-r | não mostra barra invertida para escapar quaisquer caracteres |
-s | não ecoa entrada vindo de um terminal |
-t TEMPO | esgota-se o tempo limite e retorna falha, caso uma toda uma linha não seja lida em TEMPO segundos. O valor da variável TMOUT é o tempo limite padrão. TEMPO pode ser um número fracionado. SE TEMPO for 0, `read’ retorna sucesso apenas se a entrada estiver disponível no descritor de arquivo especificado. O status de saída é maior que 128, se o tempo limite for excedido |
-u FD | lê do descritor de arquivo FD, ao invés da entrada padrão |
Exemplos
Nos seguintes exemplos vou descrever varias formas de usar o comando “read”.
Pedir dados ao utilizador
Muitas vezes os nossos scripts podem depender de dados para serem processados. Como nome de ficheiros onde precisamos guardar configurações. Dados de configuração para uma determinada aplicação, etc.
Este exemplo mostra como podemos pedir uma cor ao utilizador e guardar em uma variável, para podermos usa la depois.
#!/bin/bash
# exemplo 1
# Pedir uma cor ao utilizador
read -p 'Qual a sua cor pretendida: ' cor
# Escrever a cor preferida do utilizador
echo "A cor preferida do utilizador é '$cor'"
Correndo o script temos o seguinte resultado:
miguel@terra:~/bash/comando read$ ./comando_read_ex_1.sh
Qual a sua cor pretendida: verde
A cor preferida do utilizador é 'verde'
Neste exemplo foi usada a opção de linha de comando “-p” com o texto “Qual a sua cor pretendida: ” que queremos mostrar ao utilizador.
Foi dito ao comando que queremos guardar a cor obtida na variável “cor”.
Por fim escrevemos a cor obtida do utilizador.
Pedir uma palavra passe ao utilizador
Quando pedimos uma palavra passe temos de ter o cuidado de não a escrever no ecrã. Pois pode ser lida por alguém e comprometemos a segurança de algo.
Este exemplo mostra o caso de quando necessitamos pedir algum dado sensível ao utilizador. Quer seja uma palavra passe ou qualquer outro dado que pretendamos que seja só do conhecimento do utilizador que está a inserir os dados.
#!/bin/bash
# exemplo 2
# Pedir uma palavra passe ao utilizador
read -s -p 'Insira a Palavra Passe: ' password
# Escrever uma linha vazia, é necessário pois usamos
# a opção -s para o comando não escrever o resultado
# no ecrã.
echo
# Claro que em um caso real não queremos escrever
# no ecrã a palavra passe.
# Escrever a palavra passe do utilizador
echo "A palavra passe do utilizador é '$password'"
Correndo o script temos o seguinte resultado:
miguel@terra:~/bash/comando read$ ./comando_read_ex_2.sh
Insira a Palavra Passe:
A palavra passe do utilizador é 'uma palavra passe difícil'
Neste exemplo usei a opção de linha de comando “-s” para que o comando “read” não escreva no terminal quando o utilizador está a inserir a palavra passe que é um dado sensível.
Pedir vários dados de uma só vez
Podemos pedir vários dados de uma só vez, se for necessário. Guardado os valores em variáveis.
Por defeito os dados inseridos serão separados por “espaço” pode ser mudado se configurarmos a variável IFS.
#!/bin/bash
# exemplo 3
# Pedir várias cores de uma só vez
# e guarda las em variáveis
read -p 'Insira três cores separadas por espaço: ' cor1 cor2 cor3
# Escrever a primeira cor
echo "A primeira cor é '$cor1'"
# Escrever a segunda cor
echo "A segunda cor é '$cor2'"
# Escrever a terceira cor
echo "A terceira cor é '$cor3'"
Correndo o script temos o seguinte resultado:
miguel@terra:~/bash/comando read$ ./comando_read_ex_3.sh
Insira três cores separadas por espaço: vermelho verde amarelo
A primeira cor é 'vermelho'
A segunda cor é 'verde'
A terceira cor é 'amarelo'
Neste caso são lidas as cores e os valores são guardados nas variáveis “cor1”, “cor2”, “cor3”.
Guardar os valores inseridos em um ARRAY
Quando lemos vários dados, podemos usar um ARRAY para guardar os valores ao invés de usarmos varias variáveis. Isto é conseguido com a opção de linha de comando “-a”.
#!/bin/bash
# exemplo 4
# Pedir várias cores de uma só vez
# e guarda las em um array
read -p 'Insira três cores separadas por espaço: ' -a cores
# Escrever a primeira cor
echo "A primeira cor é '${cores[0]}'"
# Escrever a segunda cor
echo "A segunda cor é '${cores[1]}'"
# Escrever a terceira cor
echo "A terceira cor é '${cores[2]}'"
Correndo o script temos o seguinte resultado:
miguel@terra:~/bash/comando read$ ./comando_read_ex_4.sh
Insira três cores separadas por espaço: vermelho verde amarelo
A primeira cor é 'vermelho'
A segunda cor é 'verde'
A terceira cor é 'amarelo'
Neste caso pedimos ao utilizador para inserir três cores e guardamos os valores no ARRAY “cores”.
Determinar um tempo para o utilizador inserir dados
Em certas situações, é necessário limitarmos o tempo que o “read” fica à espera que o utilizador insira um determinado dado. Para o fazermos usamos a opção “-t”. A opção “-t” permite definir o numero de segundos que o “read” fica a ler dados.
O seguinte exemplo demonstra isto:
#!/bin/bash
# exemplo 5
# Predefinir um determinado tempo para o utilizador
# inserir um valor
read -p 'Insira sim se concorda: ' -t 5 resposta
ret=$?;
# Escrever uma linha vazia
echo
# O utilizador inseriu o valor a tempo?
[[ $ret -eq 0 ]] && echo "O Utilizador inseriu o valor a tempo";
# O utilizador inseriu o valor a tempo?
[[ $ret -eq 142 ]] && echo "O Utilizador não inseriu o valor a tempo";
Correndo o script temos o seguinte resultado quando damos “enter” a tempo:
miguel@terra:~/bash/comando read$ ./comando_read_ex_5.sh
Insira sim se concorda:
O Utilizador inseriu o valor a tempo
Correndo o script temos o seguinte resultado quando não damos “enter” a tempo:
miguel@terra:~/bash/comando read$ ./comando_read_ex_5.sh
Insira sim se concorda:
O Utilizador não inseriu o valor a tempo
Para sabermos a resposta, usamos a variável especial “$?” que nos mostra o retorno do comando “read”.
Ler dados de um FD diferente
Quando um script é lançado são criados normalmente 3 FDs(File Descriptor) de ficheiros. O stdin(fd 0) e stdout(fd 1) e stderr(fd 2). O comando “read” lê por defeito do fd 0 “stdin”. Quando inserimos dados estamos a escrever para um ficheiro virtual que se encontra na “/proc” do sistema.
No entanto o BASH permite criar outros FDs para que possamos usar em nossos scripts.
Neste exemplo vou criar um FD diferente e usar com o comando “read”. Em vez de o “read” ler os dados que inserimos no terminal ele vai ler deste ficheiro.
O seguinte exemplo demonstra como criar e ler a partir de um FD diferente.
#!/bin/bash
# exemplo 6
# Criar um FD(File Descriptor) 4
exec 4< cores.txt
# Ler as cores do fd 4 para um array
read -u 4 -a cores
# Escrever a primeira cor
echo "A primeira cor é '${cores[0]}'"
# Escrever a segunda cor
echo "A segunda cor é '${cores[1]}'"
# Escrever a terceira cor
echo "A terceira cor é '${cores[2]}'"
Correndo o script temos o seguinte resultado:
miguel@terra:~/bash/comando read$ ./comando_read_ex_6.sh
A primeira cor é 'vermelho'
A segunda cor é 'amarelo'
A terceira cor é 'verde'
Neste script usei a opção “-u” para informar o “read” para ler a partir do FD 4.
Redirecionar um ficheiro para o stdin do comando read
Podemos também redirecionar dados para o stdin do comando “read”.
Irei criar mais tarde um artigo sobre redirecionamentos. Aqui fica apenas o exemplo.
Para tal usamos o seguinte forma:
#!/bin/bash
# exemplo 7
# Ler as cores de um ficheiro para um array
read -a cores < cores.txt
# Escrever a primeira cor
echo "A primeira cor é '${cores[0]}'"
# Escrever a segunda cor
echo "A segunda cor é '${cores[1]}'"
# Escrever a terceira cor
echo "A terceira cor é '${cores[2]}'"
Correndo o script temos o seguinte resultado:
miguel@terra:~/bash/comando read$ ./comando_read_ex_7.sh
A primeira cor é 'vermelho'
A segunda cor é 'amarelo'
A terceira cor é 'verde'
Redirecionar o valor de uma variável para o stdin do comando read
Também podemos ler o texto de uma variavel com o comando “read”. O valor da variavel pode ser estático ou gerado pelo script com outros comandos.
Irei criar mais tarde um artigo sobre redirecionamentos. Aqui fica apenas o exemplo.
O seguinte exemplo mostra coma redirecionar o conteúdo de uma variavel para o stdin do comando “read”.
#!/bin/bash
# exemplo 8
ascores="vermelho amarelo verde"
# Ler as cores de uma variavel para um array
read -a cores <<< $ascores
# Escrever a primeira cor
echo "A primeira cor é '${cores[0]}'"
# Escrever a segunda cor
echo "A segunda cor é '${cores[1]}'"
# Escrever a terceira cor
echo "A terceira cor é '${cores[2]}'"
Correndo o script temos o seguinte resultado:
miguel@terra:~/bash/comando read$ ./comando_read_ex_8.sh
A primeira cor é 'vermelho'
A segunda cor é 'amarelo'
A terceira cor é 'verde'
Neste exemplo as cores estão guardadas na variavel “ascores” de forma estática. Mas torna se mais útil quando o valor da variavel “ascores” é gerado no script dinamicamente.
Conclusão
O comando “read” em BASH é um comando muito importante.
Perceber o seu funcionamento é importante, para elaborarmos scripts melhores.
Neste artigo tentei de forma pratica mostrar alguns exemplo de como usamos o “read”. Muitas mais utilidades existe com certeza para este comando.
Qualquer questão comentem ou usem o grupo Bash Script.