Comando de leitura Bash

Bash Read Command



Leia ou morra amigos. O comando read é tão importante quanto os parâmetros posicionais e o comando echo. De que outra forma você irá capturar a entrada do usuário, aceitar senhas, escrever funções, fazer um loop e dar uma olhada nos descritores de arquivo? Leia.

O que é lido?

Read é um comando bash embutido que lê o conteúdo de uma linha em uma variável. Ele permite a divisão de palavras vinculada à variável especial do shell IFS. É usado principalmente para capturar a entrada do usuário, mas pode ser usado para implementar funções que recebem a entrada da entrada padrão.







Bash lê a ajuda do comando integrado

Antes de mergulharmos em como usar o comando read em scripts bash, aqui está como obter ajuda. Lá você deverá ver todas as opções disponíveis para o comando de leitura junto com as descrições que tentaremos cobrir nos exemplos.



Linha de comando



ajuda leitura

Saída





leitura:leitura [-ers] [-a matriz] [-d compartilhar] [-i texto] [-n nchars] [-N nchars]
[-p prompt] [-t tempo limite] [-u fd] [nome ...]

Leia uma linha da entrada padrão edividirem campos.

Lê uma única linha da entrada padrão ou deArquivodescritor FD
E sea-vocêopção é fornecida. A linha édividirem camposComocom palavra
divisão, e a primeira palavra é atribuída ao primeiro NOME, o segundo
palavra para o segundo NOME, e assim por diante, com quaisquer palavras restantes atribuídas a
aúltimoNOME. Apenas os personagens encontradosno $ IFSsão reconhecidosComopalavra
delimitadores.

Se nenhum NOME for fornecido, a linhaleituraestá armazenadonoa variável REPLY.

Opções:
-paraarray atribuir as palavrasleiturapara índices sequenciais da matriz
variável ARRAY, começando em zero
-ddelimProsseguir atéo primeiro personagem de DELIM éleitura, em vez
do que newline
-e use Readline para obter a linhanoum shell interativo
-eutexto usar TEXTOComoo texto inicialparaLeia a linha
-nncharsRetornadepois de ler NCHARS caracteres em vez de esperar
parauma nova linha, mas respeite um delimitadorE semenos que

NCHARS personagens sãoleituraantes do delimitador
-NncharsRetornasomente depois de ler exatamente NCHARS caracteres, a menos
EOF é encontrado ouleitura vezesfora, ignorando qualquer
delimitador
-pprompt de saída da string PROMPT sem uma nova linha à direita antes
tentandoleitura
-rFaznão permitir que as barras invertidas escapem a nenhum caractere
-sFaznãojogou foraentrada vinda de um terminal
-ttempo esgotadoTempofora eRetornafracassoE separacompletolinha de
entrada não éleituraem TIMEOUT segundos. O valor do
A variável TMOUT é o tempo limite padrão. TIMEOUT pode ser um
número fracionário. Se TIMEOUT for0,leituraretorna
imediatamente, sem tentarleituraquaisquer dados, retornando
sucesso apenasE seentrada está disponível no especificado
Arquivodescritor. osaídastatus é maior que128
E seo tempo limite foi excedido
-vocêfdleituraa partir deArquivodescritor FD em vez da entrada padrão

Status de saída:
oRetornao código é zero, a menos que o fim do arquivo seja encontrado,leitura vezesFora
(no que casoistoé maior que 128), um erro de atribuição de variável

Capturando a entrada do usuário

Os scripts bash interativos não são nada sem capturar a entrada do usuário. O read builtin fornece métodos que a entrada do usuário pode ser capturada em um script bash.

Pegando uma linha de entrada

Para capturar uma linha de entrada, NOMEs e opções não são necessários para leitura. Quando NAME não é especificado, uma variável chamada REPLY é usada para armazenar a entrada do usuário.



Comandos

{
jogou fora -n 'Digite algo e pressione enter:';
leitura;
jogou foraVocê digitou$ {REPLY}
}

Saída

Digite algo e pressione Enter: algo(nova linha)
Você digitou algo

Pegando uma palavra de entrada

Para capturar uma palavra de entrada, a opção -d é necessária. No caso de uma palavra, definiríamos -d como um espaço, leia '-d'. É quando o usuário pressiona a barra de espaço para ler o REPLY com a palavra.

Observe que quando a opção -d é definida, o backspace não funciona conforme o esperado. Para retroceder, ao tentar capturar uma palavra de entrada, a opção -e pode ser usada, leia -e '-d'.

Comandos

{
jogou fora -n 'Digite algo e pressione espaço:';
leitura '-d';
jogou fora '';
jogou fora 'Você digitou$ {REPLY}'
}

Saída

Digite algo e pressione espaço: algo(espaço)
Você digitou algo

Solicitar ao usuário

Em scripts bash interativos, o prompt do usuário pode exigir uma mensagem para informar ao usuário qual entrada é esperada. Sempre podemos fazer isso usando o eco embutido. No entanto, verifica-se que existe uma opção de leitura.

Solicitar uma palavra ao usuário

Ao capturar uma palavra de entrada, usamos echo para escrever Digite algo e pressione espaço: para a saída padrão antes de ler ‘-d’. A opção -p permite que uma mensagem seja exibida antes da leitura da entrada padrão.

Comandos

{
leitura -p 'Digite algo e pressione espaço:' '-d';
jogou fora '';
jogou fora 'Você digitou$ {REPLY}'
}

Saída

Digite algo e pressione espaço: algo(espaço)
Você digitou algo

Solicitar um segredo ao usuário

Ao capturar a entrada do usuário sem que ela apareça no terminal, a opção -s é útil. read -s -p permite que você capture e oculte a entrada do usuário como segue.

Comandos

{
leitura -s -p 'Digite algo que eu prometo manter em segredo:'
jogou fora '';
jogou fora 'Seu segredo está seguro comigo';não definidoRESPONDER ;
jogou fora '$ {REPLY}'
}

Saída

Digite algo que eu prometo manter em segredo:
Seu segredo está seguro comigo

Funções usando leitura

Aqui estão alguns exemplos de funções em bash que usam leitura e entrada padrão

Conceito central

As funções que usam read usam entrada e parâmetros padrão canalizados. A entrada principal a ser processada, como linhas em um arquivo, são transmitidas por meio da entrada padrão por meio de um tubo. Outras entradas if-any e option são passadas como parâmetros.

leitura -t 1NAME1 NAME2 ...

leituraé umconstruídas em comando

-t 1 evita que o script bash espere indefinidamente pelo retorno de uma linha por meio da entrada padrão. Se a entrada padrão estiver inicialmente vazia, a função retorna com um código de saída de 142, significando que nenhuma data foi lida dentro do período de tempo limite definido

NAME1 NAME2 são nomes de variáveis

... muitos nomes de variáveis ​​podem ser listados

Agora que as bases estão definidas, vamos ver quais funções familiares parecem implementadas usando read.

Função Join usando read

Suponha que queremos uma função de junção que recebe uma lista de palavras e retorna outra lista de palavras unidas por um delimitador. Aqui está como podemos implementar uma função de junção usando read.

Roteiro

#! / bin / bash
## Junte
## versão 0.0.2 - corrigir parâmetros de recursão
############################################################### #
Junte() { { locallimitador;limitador='$ {1-}';localoutdelimiter;
outdelimiter='$ {2-.}';}
localcarro
localcdr
localIFS
IFS='$ {indelimiter}'
leitura -t 1carro cdr|| Retorna
teste '$ {cdr}' || { jogou fora '$ {carro}';Retorna;}
jogou fora '$ {carro}$ {outdelimiter}$ {cdr}' | $ {FUNCNAME} '$ {indelimiter}'
'$ {outdelimiter}'
}
############################################################### #
## gerado por create-stub2.sh v0.1.2
## na segunda-feira, 17 de junho de 2019 12:24:59 +0900
## Vejo
############################################################### #

Fonte: join.sh
Linha de comando

jogou foraa b| Junte

Saída

a.b

Linha de comando

jogou foraa b| Junte | Junte. |

Saída

para|b

Funções de mapa usando leitura

Suponha que desejamos uma função de mapa que recebe uma lista e retorna outra lista contendo o mesmo número de elementos que são modificados por outra função. Aqui está como podemos implementar uma função de mapa usando read.

Roteiro

#! / bin / bash
## map
## versão 0.0.1 - inicial
############################################################### #
mapa() { { localfunction_name;function_name='$ {1}';}
localcarro
localcdr
localIFS
IFS='$ {indelimiter-}'
leitura -t 1carro cdr|| Retorna
teste '$ (declara -f $ {function_name})' || Retorna
teste '$ {carro}' || { verdade;Retorna;}
$ {function_name} $ {carro}
jogou fora '$ {cdr}' | $ {FUNCNAME} '$ {function_name}'
}
############################################################### #
## gerado por create-stub2.sh v0.1.2
## na terça, 18 de junho de 2019 08:33:49 +0900
## Vejo
############################################################### #

Fonte: map.sh
Comandos

NS() { local -eu eu=$ {1};jogou fora$((eu** 2 ));}
jogou fora {1..10} |mapa pow

Saída

1
4
9
16
25
36
49
64
81
100

Função de filtro usando leitura

Suponha que desejamos uma função de filtro que recebe uma lista e retorna uma sublista de elementos que satisfazem as condições definidas por outra função. Aqui está como podemos implementar uma função de filtro usando read.

Roteiro

#! / bin / bash
## filter
## versão 0.0.1 - inicial
############################################################### #
filtro() { { localfunction_name;function_name='$ {1}';}
localcarro
localcdr
localIFS
IFS='$ {indelimiter-}'
leitura -t 1carro cdr|| Retorna
teste '$ (declara -f $ {function_name})' || Retorna
teste '$ {carro}' || { verdade;Retorna;}
$ {function_name} '$ {carro}' || jogou fora -n '$ {carro}'
jogou fora '$ {cdr}' | $ {FUNCNAME} '$ {function_name}'
}
############################################################### #
## gerado por create-stub2.sh v0.1.2
## na terça-feira, 18 de junho de 2019 13:19:54 +0900
## Vejo
############################################################### #

Fonte: filter.sh

Comandos

ímpar() { local -eu eu=$ {1};teste !$((eu% 2 )) -eq 1;}
jogou fora {1..10} |filtro estranho

Saída

1 3 5 7 9

Loops usando leitura

Os loops que usam leitura permitem que você itere através das linhas de um arquivo que deve ser gerado ou que já existe.

Básico durante o loop de leitura para o lado esquerdo (lhs)

Temos um comando ou função (lhs) que pode gerar linhas em um arquivo que pode ser executado em loop usando read e um loop while.

Construir

lhs| enquanto leitura
Faz
verdade
feito
lhs é umcomandoque retorna uma lista de linhas

Comandos

seq 5 | enquanto leituraeu
Faz
jogou fora $ {i}
feito

Saída

1
2
3
4
5

Loop de leitura ao mesmo tempo básico para o lado direito (rhs)

Temos um arquivo (rhs) com linhas que podem ser repetidas usando read e um loop while.

Construir

enquanto leitura
Faz
verdade
feito <rhs

rhs é umArquivocontendo linhas

Comandos

seq 5 >rhs
enquanto leituraeu
Faz
jogou fora $ {i}
feito <rhs

Saída

1
2
3
4
5

Custom lhs while loop usando read

Temos um fluxo de palavras que gostaríamos de percorrer usando read.

Construir

(
IFS=''
lhs| enquanto leitura
Faz
verdade
feito
)

lhs é uma lista de palavras

Comandos

(
IFS=''
jogou fora {1..5} | enquanto leituraeu
Faz
jogou fora '$ {i}
feito
)

Saída

1 2 3 4 5

Leitura de qualquer fd em vez da entrada padrão

A opção integrada de leitura freqüentemente deixada intacta é aquela que permite que você especifique qual descritor de arquivo ler, leia -u FD. Por padrão, FD é considerado uma entrada padrão.

Conceito central

Quando um arquivo aberto, descritores de arquivo são atribuídos. O redirecionamento IO no bash permite que um arquivo seja deixado aberto com um descritor de arquivo específico. Temos permissão para gravar no arquivo, ler a partir dele e fechá-lo quando terminarmos.

_()
{
gato /dev/nulo>myfifo;# vazio myfifo
exec 3<myfifo;# abra o arquivo myfifo como fd 3
jogou fora 'Olá Mundo! - de fd 3 ' >myfifo;# escreva para myfifo
leitura -você 3;# ler linha de fd 3
exec 3> &-;# close fd 3
jogou fora $ {REPLY} # linha de saída lida de fd 3 antes de fechar
}
_# Olá Mundo! do fd 3

Construindo um trem com descritores de arquivo e leia -u FD

Apenas por diversão, decidi construir um trem com descritores de arquivo e ler -u FD. Para cada descritor de arquivo, um número é escrito. Cada descritor de arquivo lê a partir do descritor de arquivo 1 abaixo e se anexa a si mesmo.

Linha de comando

bashlinuxhint.com/construir/test-read-fd.sh train10

Saída

inicializando fds ...
inicializando fd3...
fd3inicializado
inicializando fd4...
fd4inicializado
fds inicializado
lendo de fd3e4...
4 3
fds antes de limpar
0 1 2 3 4 5
limpando ...
limpando fds ...
feitolimpando fds
fds após a limpeza
0 1 2 3

Pular função usando ler -u FD

Se você está correndo

uname -para
MINGW64_NT-10,0DESKTOP-XVVVVVV 2.7.0(0,307/5/3)
2017-02-17 14:vintex86_64 Msys
bash --versão
GNUbash, versão 4.4.12(1)-liberar(x86_64-pc-msys)

pode ser possível devido a um bug para implementar uma função de salto que salta a seguinte linha em um script bash fora das funções antes que o código-fonte do script seja lido. Observe que ele não funciona na maioria dos sistemas. Por exemplo,

uname -para
Linux 4.9.0-8-amd64# 1 Debian SMP 4.9.144-3.1 (19/02/2019) x86_64 GNU / Linux
bash --versão
GNUbash, versão 4.4.12(1)-liberar(x86_64-pc-linux-gnu)

pular não voa.

Função

pular() { leitura -você 31;}

Comandos

pular
jogou foralinha pulada
verdade

Saída

(vazio)

Resultado

A leitura embutida no bash faz mais do que capturar a entrada do usuário. Ele pode ser usado em funções, loops e trocas entre descritores de arquivo usados ​​em scripts bash. Ocasionalmente, a exploração usando descritores de leitura e de arquivo pode render ovos de Páscoa.