¿Podría alguien explicar cómo funciona el siguiente código?
echo '1 2 3 4 5 6' | while read a b c
do
echo $c $b $a
done
Específicamente, me gustaría saber por qué la salida de este bucle es 3 4 5 6 2 1
, en lugar de 3 2 1
y 6 5 4
en dos líneas separadas. Parece que no puedo entenderlo ...
Reescribir el ciclo de esta manera revela lo que está sucediendo:
Esto da, como su salida:
Observe primero que solo se ejecuta un comando echo. Si se ejecutara más de una vez, vería, entre otras cosas, las subcadenas
(iteration beginning)
e(iteration ending)
impresas más de una vez.Esto quiere decir que tener un
while
bucle aquí no es realmente lograr nada. Elread
archivo incorporado lee el texto separado por espacios en blanco 1 en cada variable especificada. La entrada adicional se agrega al final de la última variable especificada. 2 Así, las variablesa
yb
toman los valores1
y2
respectivamente, mientras quec
toman el valor3 4 5 6
.Cuando la condición del bucle (
while read a b c
) se evalúa por segunda vez, no hay más entradas disponibles desde la tubería (solo lo canalizamos una sola línea de texto), por lo que elread
comando se evalúa como falso en lugar de verdadero y el bucle se detiene (antes de ejecutar el cuerpo por segunda vez).1 : Para ser técnico y específico, el
read
incorporado , cuando pasa los nombres de las variables como argumentos, lee la entrada, dividiéndola en "palabras" separadas cuando encuentra espacios en blanco IFS (vea también esta pregunta y este artículo ).2 :
read
el comportamiento de bloquear cualquier campo adicional de entrada en la última variable especificada no es intuitivo para muchos scripters, al principio. Se vuelve más fácil de entender cuando se considera que, como dice la respuesta de Florian Diesch ,read
siempre (intentará) leer una línea completa, y queread
está destinada a ser utilizable con y sin bucle.fuente
while
no cumplía su propósito normal en este ejemplo, pero luego elread
comando me arrojó ... De alguna manera, lo interpreté como "mientrasread a b c
no sea falso, hazloecho ...
". Gracias por explicar cómo funcionó realmente. Me encontré con este código ayer y sabía que me molestaría hasta que lo descubriera ... jajajaread a b c
evalúa como verdadero, y la condición del bucle (read a b c
) se ejecuta más de una vez. Bit solo se evalúa como verdadero la primera vez. La segunda vez, no hay más entradas para leer desde la tubería, por lo que se encuentra el final del archivo , loread
que hace que se devuelva falso . (Consulte la última sección de la salida dehelp read
, en "Estado de salida", para obtener detalles, y observe que, en las secuencias de comandos de shell, cero significa verdadero y no cero significa falso). Si conecta más de una línea de entradawhile read ...
, el cuerpo del bucle ser ejecutado varias veces.