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
,read
interpretará 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-r
para evitar que os caracteres desapareçam no caso raro de haver barras invertidas na entrada. -
O fato de que
read
retorna 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; done
porque falhará emdo something
com a última linha no caso raro de a última linha não ter uma nova linha no final. -
read -r LINE
preserva barras invertidas, mas não preserva espaços em branco iniciais ou finais.