Ce qui doit être expliqué est que la commande semble fonctionner, pas son code de sortie
'\n'est composé de deux caractères: une barre oblique inverse \et une lettre n. Ce dont vous pensiez avoir besoin, c'était d' $'\n'un saut de ligne (mais ce ne serait pas bien non plus, voir ci-dessous).
L' -doption fait ceci:
-d delim continue until the first character of DELIM is read, rather
than newline
Donc, sans cette option, readlirait jusqu'à une nouvelle ligne, diviserait la ligne en mots en utilisant les caractères $IFScomme séparateurs et placerait les mots dans le tableau. Si vous spécifiez -d $'\n', en définissant le délimiteur de ligne sur une nouvelle ligne, cela ferait exactement la même chose . Le réglage -d '\n'signifie qu'il sera lu jusqu'à la première barre oblique inverse (mais, encore une fois, voir ci-dessous), qui est le premier caractère de delim. Puisqu'il n'y a pas de barre oblique inverse dans votre fichier, le readse terminera à la fin du fichier et:
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.
C'est pourquoi le code de sortie est 1.
Du fait que vous pensez que la commande a fonctionné, nous pouvons conclure qu'il n'y a pas d'espaces dans le fichier, de sorte qu'après readavoir lu l'intégralité du fichier dans l'espoir futile de trouver une barre oblique inverse, il sera divisé par des espaces (la valeur par défaut de $IFS), y compris les sauts de ligne. Ainsi, chaque ligne (ou chaque mot, si une ligne contient plusieurs mots) est stockée dans le tableau.
Le cas mystérieux de la barre oblique inversée
Maintenant, comment savais-je que le fichier ne contenait aucune barre oblique inverse? Parce que vous n'avez pas fourni le -rdrapeau à read:
-r do not allow backslashes to escape any characters
Donc, si vous aviez des barres obliques inverses dans le fichier, elles auraient été supprimées, à moins que vous n'en ayez deux de suite. Et, bien sûr, il y a des preuves qui readavaient un code de sortie de 1, ce qui démontre qu'il n'a pas trouvé de barre oblique inverse, donc il n'y en avait pas deux de suite non plus.
Plats à emporter
Bash ne serait pas bash s'il n'y avait pas de pièges cachés derrière à peu près toutes les commandes, et readne fait pas exception. En voici deux:
Sauf indication contraire -r, readinterprètera les séquences d'échappement de barre oblique inverse. À moins que ce ne soit réellement ce que vous voulez (ce qui est occasionnellement, mais seulement occasionnellement), vous devez vous rappeler de spécifier -rpour éviter que les caractères disparaissent dans les rares cas où il y a des barres obliques inverses dans l'entrée.
Le fait que readrenvoie un code de sortie de 1 ne signifie pas qu'il a échoué. Il a peut-être bien réussi, sauf pour trouver le terminateur de ligne. Soyez donc prudent avec une boucle comme celle-ci: while read -r LINE; do something with LINE; done
car elle échouera do somethingavec la dernière ligne dans le cas rare où la dernière ligne n'a pas de nouvelle ligne à la fin.
read -r LINE conserve les barres obliques inverses, mais ne préserve pas les espaces de début ou de fin.