-
O comando
read
lê seu fluxo de entrada padrão e atribui o que é lido à variávelfile
(é um pouco mais complicado do que isso, consulte longa discussão aqui ). O fluxo de entrada padrão vem do documento aqui redirecionado para o loop apósdone
. Se não for dado dados de qualquer lugar , ele lerá do terminal, interativamente. Neste caso, porém, o shell conseguiu conectar seu fluxo de entrada ao documento here. -
while read
fará com que o loop faça uma iteração até que o comandoread
retorne um status de saída diferente de zero. Isso acontecerá se houver algum erro ou (mais comumente) quando não houver mais dados a serem lidos (seu fluxo de entrada está em um estado de fim de arquivo).A convenção é que qualquer utilitário que deseje sinalizar um erro ou "falso" ou "não" para o shell de chamada faz isso retornando um status de saída diferente de zero. Um status de saída zero sinaliza "true" ou "yes" ou "sem erro". Este status, você gostaria de inspecioná-lo, está disponível em
$?
(somente a partir do último utilitário executado). O status de saída pode ser usado emif
declarações ewhile
loops ou em qualquer lugar onde um teste é necessário. Por exemploif grep -q 'pattern' file; then ...; fi
-
Um documento aqui é uma forma de redirecionamento . Neste caso, é um redirecionamento para o loop. Qualquer coisa dentro do loop poderia ler a partir dele, mas neste caso é apenas o comando
read
que faz. Leia os documentos aqui. Se a entrada estava vindo de um arquivo comum, a última linha teria sidodone <filename
Ver o loop como um único comando pode tornar isso mais intuitivo:
while ...; do ...; done <filename
que é um caso de
somecommand <filename
Algumas shells também suportam "here-strings" com
<<<"string"
:cat <<<"This is the here-string"
DavidFoerster aponta que se qualquer um dos dois scripts
x.sh
ey.sh
ler a entrada padrão, sem explicitamente receber dados para ler de um arquivo ou de outro lugar, os dados lidos na verdade virão daqui -documento.Com um
x.sh
que contém apenasread a
, isso faria com que a variávela
contivesse a stringy.sh
e o scripty.sh
nunca fosse executado. Isso se deve ao fato de que a entrada padrão é redirecionada para os comandos all no loopwhile
(e também "herdada" por qualquer script ou comando invocado) e a segunda linha é "consumida" porx.sh
antes que owhile
doread
possa lê-lo.Se esse comportamento não for desejado, ele poderá ser evitado, mas é um pouco complicado .
-
Falha porque não há
;
ou nova linha antes dedone
. Sem;
ou newline antes dedone
, a palavradone
será considerada como um argumento desource
, e o loop também não será fechado adequadamente (isso é um erro de sintaxe).É quase verdade que qualquer
;
pode ser substituído por uma nova linha (pelo menos quando é um delimitador de comando). Ele sinaliza o final de um comando, assim como|
,&
,&&
e||
(e provavelmente outros que eu esqueci).