¿Cuál es el propósito de la palabra clave "hacer" en Bash para bucles?

76

¿Cuál es el propósito de la dopalabra clave en la forsintaxis del bucle Bash ? Para mí, se siente redundante.

for i in `seq 1 2`; do echo "hi"; done

¿Por qué la sintaxis no es así?

for i in `seq 1 2`; echo "hi"; done

Estoy seguro de que cumple un propósito. Solo quiero aprender

Fredrik Johansson
fuente

Respuestas:

118

Tenga en cuenta que esa sintaxis se hereda del shell Bourne.

Después del nombre de la variable, puede tener inque tener la lista de elementos dada explícitamente o dohacer un bucle sobre los parámetros posicionales.

for i in 1 2 3
do
  echo "$i"
done

O

set 1 2 3
for i do
  echo "$i"
done

Tenerlo doen ambos casos (incluso si no es estrictamente necesario en el primero) genera una sintaxis más consistente. También es consistente con los bucles while/ untildonde does necesario.

while
  cmd1
  cmd2
do
  cmd3
  cmd4
done

Necesita el dopara decir dónde termina la lista de comandos de condición .

Tenga en cuenta que el shell Bourne no era compatible for i; do. Esa sintaxis tampoco fue POSIX hasta la edición 2016 del estándar ( for i dosiempre ha sido POSIX; vea el error relacionado con el grupo de Austin ).

zsh tiene algunas formas abreviadas como:

for i in 1 2 3; echo $i
for i (1 2 3) echo $i
for ((i=1;i<=3;i++)) echo $i

O soporte para más de una variable:

for i j (1 a 2 b) echo $i $j

(aunque no puede usar ino docomo nombre de variable en lugar de jarriba).

Incluso si rara vez se documenta, la mayoría de los shells tipo Bourne (Bourne, ksh, bash, zsh, not ashni yash) también admiten:

for i in 1 2 3; { echo "$i";}

El shell Bourne kshy zsh(pero no bash) también admiten:

for i { echo "$i"; }

Mientras bash, kshy zsh(pero no el shell Bourne) soporte:

for i; { echo "$i"; }

Todos (Bourne, bash, ksh, zsh) de soporte:

for i
{ echo "$i";}

ksh93, bash, zshSoporte:

for ((i=1;i<=3;i++)) { echo "$i"; }
Stéphane Chazelas
fuente
2
Como siempre, respuesta completa y perfecta (con una referencia a zsh) ...
Kiwy
2
No es "estrictamente necesario" en ninguno de los casos for; el comando puede ser terminado por una nueva línea o punto y coma. Tiene un poco más de sentido para if/ while(el primero con en thenlugar de do), pero en principio esos podrían haberlo omitido y requerido una subshell o llaves para el uso (raro) de múltiples comandos. Sospecho que la verdadera razón por la que lo hace el shell Bourne es porque ALGOL lo hace, y deberíamos alegrarnos de que doneno se deletree od.
Random832
44
@ Random832: Eso es porque odya se usaba como el nombre del programa Octal Dump.
user1024
8
Hay tanto aquí que no sabía. ¡Gracias!
ligereza corre en órbita el
1
@mirabilos, for i does Bourne y POSIX, pero no funcionará en algunas versiones antiguas de conchas de cenizas IIRC. for i in "$@"no funcionará en el shell Bourne si $IFSno contiene el carácter de espacio. for i<newline>does de hecho el más portátil si necesita considerar sistemas BSD muy antiguos. Ver in-ulm.de/~mascheck/various/bourne_args para más detalles
Stéphane Chazelas