O que precisa ser explicado é que o comando parecia funcionar, não seu código de saída
'\n'
tem dois caracteres: uma barra invertida \e uma letra n. O que você pensou que precisava era $'\n'
, que é um avanço de linha (mas isso também não seria correto, veja abaixo).
A -d
opção faz isso:
-d delim continue until the first character of DELIM is read, rather
than newline
Portanto, sem essa opção, read
seria possível ler uma nova linha, dividir a linha em palavras usando os caracteres $IFS
como separadores e colocar as palavras na matriz. Se você especificou -d $'\n'
, definindo o delimitador de linha como uma nova linha, ele faria exatamente a mesma coisa . Configuração -d '\n'
significa que ele lerá a primeira barra invertida (mas, mais uma vez, veja abaixo), que é o primeiro caractere delim
. Como não há barra invertida em seu arquivo, o read
final será no final do arquivo e:
Exit Status:
The return code is zero, unless end-of-file is encountered, read times out,
or an invalid file descriptor is supplied as the argument to -u.
É por isso que o código de saída é 1.
Pelo fato de você acreditar que o comando funcionou, podemos concluir que não há espaços no arquivo, para que read
, depois de ler o arquivo inteiro na esperança fútil de encontrar uma barra invertida, o divida por espaço em branco (o valor padrão de $IFS
), incluindo novas linhas. Portanto, cada linha (ou cada palavra, se uma linha contiver mais de uma palavra) é armazenada na matriz.
O misterioso caso da barra invertida roubada
Agora, como eu sabia que o arquivo não continha barras invertidas? Porque você não forneceu a -r
bandeira para read
:
-r do not allow backslashes to escape any characters
Portanto, se você tivesse barras invertidas no arquivo, elas teriam sido removidas, a menos que você tivesse duas delas seguidas. E, é claro, existem evidências de que read
havia um código de saída 1, o que demonstra que ele não encontrou uma barra invertida; portanto, não havia dois deles seguidos.
Aprendizado
Bash não seria uma festa, se não houvesse truques escondidos atrás de quase todos os comandos, e read
não é exceção. Aqui estão alguns:
A menos que você especifique -r
, read
interpretará as seqüências de escape de barra invertida. A menos que seja realmente o que você deseja (o que ocasionalmente é, mas apenas ocasionalmente), lembre-se de especificar -r
para evitar que os caracteres desapareçam, no caso raro de haver barras invertidas na entrada.
O fato de read
retornar um código de saída 1 não significa que ele falhou. Pode ter sido bem-sucedido, exceto para encontrar o terminador de linha. Portanto, tenha cuidado com um loop como este: while read -r LINE; do something with LINE; done
porque falhará do something
com a última linha no caso raro de que a última linha não tenha uma nova linha no final.
read -r LINE
preserva barras invertidas, mas não preserva os espaços em branco à esquerda ou à direita.
while read
". Caso contrário, resposta fantástica.while read
desde que não tenha nada dentro do loop. Caso contrário, é um bug esperando para morder você - e acredite, fui mordido.read
.mapfile
é bem legal. Para um hack rápido e sujo, usarei o loop while proibido, mas parei de colocar isso nos scripts de produção. YMMV e eu suavizamos o aviso na resposta.Esse é o comportamento esperado:
fonte