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 -d
opción hace esto:
-d delim continue until the first character of DELIM is read, rather
than newline
Entonces, sin esa opción, read
leería hasta una nueva línea, dividiría la línea en palabras usando los caracteres $IFS
como 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, read
terminará 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 -r
bandera 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 read
tení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 read
no es una excepción. Aquí hay una pareja:
A menos que especifique -r
, read
interpretará las secuencias de escape de barra invertida. A menos que sea realmente lo que desea (que ocasionalmente es, pero solo ocasionalmente), debe recordar especificar -r
para evitar que los caracteres desaparezcan en el raro caso de que haya barras invertidas en la entrada.
El hecho de que read
devuelva 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 something
con 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 read
siempre que no tengas nada dentro del bucle. De lo contrario, es un error esperando morderte, y créeme, he sido mordido.read
.mapfile
es 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