Lo que debe explicarse es que el comando parecía funcionar, no su código de salida
'\n'tiene dos caracteres: una barra diagonal inversa \y una letra n. Lo que pensabas que necesitabas era $'\n', que es un salto de línea (pero eso tampoco sería correcto, ver más abajo).
La -dopción hace esto:
-d delim continue until the first character of DELIM is read, rather
than newline
Entonces, sin esa opción, readleería hasta una nueva línea, dividiría la línea en palabras usando los caracteres $IFScomo separadores y colocaría las palabras en la matriz. Si lo especificó -d $'\n', estableciendo el delimitador de línea en una nueva línea, haría exactamente lo mismo . La configuración -d '\n'significa que se leerá hasta la primera barra diagonal inversa (pero, una vez más, vea a continuación), que es el primer carácter en delim. Como no hay una barra invertida en su archivo, readterminará al final del archivo y:
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 eso el código de salida es 1.
Por el hecho de que usted cree que el comando funcionó, podemos concluir que no hay espacios en el archivo, por lo que read, después de leer todo el archivo con la vana esperanza de encontrar una barra invertida, lo dividirá por espacios en blanco (el valor predeterminado de $IFS), incluidas las nuevas líneas. Por lo tanto, cada línea (o cada palabra, si una línea contiene más de una palabra) se almacena en la matriz.
El misterioso caso de la barra invertida robada
Ahora, ¿cómo supe que el archivo no contenía barras invertidas? Porque no proporcionó la -rbandera a read:
-r do not allow backslashes to escape any characters
Entonces, si tuviera barras diagonales inversas en el archivo, se habrían eliminado, a menos que tuviera dos de ellas seguidas. Y, por supuesto, existe la evidencia de que readtenía un código de salida de 1, lo que demuestra que no encontró una barra invertida, por lo que tampoco había dos seguidos.
Comida para llevar
Bash no sería bash si no hubiera trampas escondiéndose detrás de casi todos los comandos, y readno es una excepción. Aquí hay una pareja:
A menos que especifique -r, readinterpretará las secuencias de escape de barra invertida. A menos que sea realmente lo que desea (que ocasionalmente es, pero solo ocasionalmente), debe recordar especificar -rpara evitar que los caracteres desaparezcan en el raro caso de que haya barras invertidas en la entrada.
El hecho de que readdevuelva un código de salida de 1 no significa que haya fallado. Bien pudo haber tenido éxito, excepto por encontrar el terminador de línea. Así que tenga cuidado con un ciclo como este: while read -r LINE; do something with LINE; done
porque fallará do somethingcon la última línea en el raro caso de que la última línea no tenga una nueva línea al final.
read -r LINE conserva las barras invertidas, pero no conserva los espacios en blanco iniciales o finales.
while read". De lo contrario, respuesta fantástica.while readsiempre que no tengas nada dentro del bucle. De lo contrario, es un error esperando morderte, y créeme, he sido mordido.read.mapfilees bastante bueno. Para un hack rápido y sucio, usaré el bucle while prohibido, pero he dejado de poner eso en los scripts de producción. YMMV y yo suavizamos la advertencia en la respuesta.Ese es el comportamiento esperado:
fuente