O que precisa ser explicado é que o comando pareceu funcionar, não o seu código de saída
'\n' é dois caracteres: uma barra invertida \ e uma letra n . O que você achou que precisava era $'\n' , que é um avanço de linha (mas isso também não seria correto, veja abaixo).
A opção -d faz isso:
-d delim continue until the first character of DELIM is read, rather than newline
Portanto, sem essa opção, read leria uma nova linha, dividiria a linha em palavras usando os caracteres em $IFS como separadores e colocaria as palavras na matriz. Se você especificou -d $'\n' , definindo o delimitador de linha para uma nova linha, ele faria exatamente a mesma coisa . A configuração -d '\n' significa que ele será lido até a primeira barra invertida (mas, mais uma vez, veja abaixo), que é o primeiro caractere em delim . Como não há barra invertida em seu arquivo, o read terminará 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.
Então é por isso que o código de saída é 1.
Do fato de você acreditar que o comando funcionou, podemos concluir que não há espaços no arquivo, de modo que read , depois de ler o arquivo inteiro na esperança inútil de encontrar uma barra invertida, o dividirá por espaço em branco (o valor padrão de $IFS ), incluindo novas linhas. Assim, cada linha (ou cada palavra, se uma linha contiver mais de uma palavra) é colocada no array.
O caso misterioso da barra invertida
Agora, como eu sabia que o arquivo não continha barras invertidas? Porque você não forneceu o -r flag para read :
-r do not allow backslashes to escape any characters
Então, se você tivesse alguma barra invertida no arquivo, eles seriam removidos, a menos que você tivesse dois deles seguidos. E, claro, há a evidência de que read tinha um código de saída igual a 1, o que demonstra que ele não encontrou uma barra invertida, portanto não havia duas delas seguidas.
Takeaways
Bash não seria nada se não houvesse pegadinhas se escondendo atrás de quase todos os comandos, e read não é exceção. Aqui está um casal:
-
A menos que você especifique
-r,readinterpretará seqüências de escape de barra invertida. A menos que seja realmente o que você quer (o que ocasionalmente é, mas apenas ocasionalmente), você deve se lembrar de especificar-rpara evitar que os caracteres desapareçam no caso raro de haver barras invertidas na entrada. -
O fato de que
readretorna um código de saída de 1 não significa que ele falhou. Pode ter sido bem sucedido, exceto por encontrar o terminador de linha. Portanto, tenha cuidado com um loop como este:while read -r LINE; do something with LINE; doneporque falhará emdo somethingcom a última linha no caso raro de a última linha não ter uma nova linha no final. -
read -r LINEpreserva barras invertidas, mas não preserva espaços em branco iniciais ou finais.