Como funciona o comando WHILE internamente quando utilizamos o READ ?

1. Como funciona o comando WHILE internamente quando utilizamos o READ ?

Mestre Kame
mlgrassi

(usa Debian)

Enviado em 17/07/2018 - 13:22h

Estou com uma dúvida e gostaria de saber se alguém pode me ajudar.

No exemplo a seguir, o while está recebendo como entrada um arquivo fictício contendo 1 milhão de linhas e irá apenas exibir o resultado.

while read LINE;do
echo $LINE;
done <arquivo_teste.txt


Agora pergunto: o que ocorre neste caso, todas as linhas contidas no arquivo serão primeiramente atribuídas à variável LINE para somente depois serem impressas, ou o while joga todo o conteúdo do arquivo para um buffer para somente depois LINE ser populada por completo? Ou LINE será alterada a cada interação? Quais os problemas de utilizar o while dessa maneira?


  


2. Re: Como funciona o comando WHILE internamente quando utilizamos o READ ?

Slackjeff
slackjeff

(usa Slackware)

Enviado em 17/07/2018 - 14:59h

Eles são lidos linha a linha, como um laço For, não ficando armazenado todo conteudo para depois imprimir!
Não tem problema em usar esse whilezinho, em alguns casos quando não quero utilizar nenhuma ferramenta externa eu uso ele ao invés do cat por exemplo...


THE MAGIC SHELL PROGRAMMER.

Slackware user since ~2008
Meu canal no youtube:
https://www.youtube.com/SlackJeff

Meu Site:
http://www.slackjeff.com.br/

Meus Programas estão aqui:
https://notabug.org/jeffersonrocha

Meu PODCAST:
http://podcast.slackjeff.com.br/







3. Re: Como funciona o comando WHILE internamente quando utilizamos o READ ?

Paulo
paulo1205

(usa Ubuntu)

Enviado em 22/07/2018 - 01:27h

Um importante cuidado que eu recomendo com uma construção como essa é que você se lembre que o redirecionamento afeta tudo o que vai dentro do laço de repetição. Assim sendo, se você tiver um comando que eventualmente possa consumir dados da entrada padrão, isso pode acabar afetando as condições de controle do loop.

Veja estes exemplos:

$ while read linha; do
echo $linha
sh -c 'read x'
done < <(seq 1 10)

1
3
5
7
9
$


$ while read linha; do
echo $linha
ssh 127.0.0.1 '/bin/true'
done < <(seq 1 10)

1
$


Esse é um dos motivos pelos quais eu geralmente prefiro maneiras de ter um controle mais específico dos redirecionamentos. Veja os exemplos abaixo.

exec 3< <(seq 1 10)   # Joga a saída do comando no descritor 3 do shell.
while read -u 3 linha # Note que eu mando explicitamente ler do descritor 3.
do
echo $linha
sh -c 'read x' # Este subshell vai ler do descritor 0, logo não haverá conflito.
done
exec 3<&- # Fecha o descritor 3 após o fim do laço de repetição.


No exemplo acima, não haverá interferência porque o shell externo está controlando o laço de repetição usando o descritor 3, e o shell interno está tentando ler do descritor 0, que é a entrada padrão. Contudo, todos os descritores abertos pelo shell são herdados pelos processos filhos, de modo que poderia haver interferência se um comando explicitamente tentar mexer num desses descritores herdados.

exec 3< <(seq 1 10)
while read -u 3 linha; do
echo $linha
sh -c 'read x <&3' # Este subshell explicitamente lê do descritor 3, herdado do shell pai.
done
exec 3<&-


Essa situação pode ser desejável em alguns casos, mas normalmente não o é. Assim sendo, eu posso fazer com que o shell pai explicitamente feche aquele descritor na hora de executar um comando.

exec 3< <(seq 1 10)
while read -u 3 linha; do
echo $linha
sh -c 'read x <&3' 3<&- # O shell pai explcitamente fecha o descritor para o processo filho (neste caso, o subshell vai gerar erro).
done
exec 3<&-


Se for um conjunto de comandos, pode-se fechar o descritor para todos eles através de um agrupamento de comandos entre chaves.

exec 3< <(seq 1 10)
while read -u 3 linha; do
echo $linha
{
comando1
comando2
# ...
comandoN
} 3<&-
done
exec 3<&-



4. Re: Como funciona o comando WHILE internamente quando utilizamos o READ ?

Paulo
paulo1205

(usa Ubuntu)

Enviado em 22/07/2018 - 02:10h

NOTA: Na mensagem anterior, eu fiz todos os exemplos com redirecionamento a partir de um comando bem conhecido e com saída previsível, usando a notação de named pipes implícitos do KSH e do Bash. Mas o redirecionamento pode ser de arquivos comuns, sem passar por named pipes.

exec 3< /etc/passwd
while read -u 3 linha; do
echo $linha
{
cmd1
# ...
cmdN
} 3<&-
done
exec 3<&-




  



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts