-
O comando
readlê 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 readfará com que o loop faça uma iteração até que o comandoreadretorne 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 emifdeclarações ewhileloops 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
readque faz. Leia os documentos aqui. Se a entrada estava vindo de um arquivo comum, a última linha teria sidodone <filenameVer o loop como um único comando pode tornar isso mais intuitivo:
while ...; do ...; done <filenameque é um caso de
somecommand <filenameAlgumas shells também suportam "here-strings" com
<<<"string":cat <<<"This is the here-string"DavidFoerster aponta que se qualquer um dos dois scripts
x.shey.shler 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.shque contém apenasread a, isso faria com que a variávelacontivesse a stringy.she o scripty.shnunca 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.shantes que owhiledoreadpossa 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 palavradoneserá 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).