Qual é o objetivo da palavra-chave "do" no Bash para loops?

76

Qual é o objetivo da dopalavra - chave na forsintaxe do loop Bash ? Para mim, parece redundante.

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

Por que a sintaxe não é assim?

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

Tenho certeza de que ele cumpre um propósito. Eu só quero aprender.

Fredrik Johansson
fonte

Respostas:

118

Observe que essa sintaxe é herdada do shell Bourne.

Após o nome da variável, você pode ter ina lista de elementos fornecida explicitamente ou dofazer um loop sobre os parâmetros posicionais.

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

Ou

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

Ter os dodois casos (mesmo que não seja estritamente necessário no primeiro) cria uma sintaxe mais consistente. Também é consistente com os loops while/ untilonde doé necessário.

while
  cmd1
  cmd2
do
  cmd3
  cmd4
done

Você precisa dodizer onde termina a lista de comandos de condição .

Observe que o shell Bourne não suportava for i; do. Essa sintaxe também não foi POSIX até a edição de 2016 do padrão ( for i dosempre foi POSIX; veja o bug do grupo Austin relacionado ).

zsh tem algumas 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

Ou suporte para mais de uma variável:

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

(embora você não possa usar inou docomo nome da variável no lugar jacima).

Mesmo raramente documentado, a maioria dos shells tipo Bourne (Bourne, ksh, bash, zsh, not ashnem yash) também suporta:

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

O shell Bourne kshe zsh(mas não bash) também suportam:

for i { echo "$i"; }

Enquanto bash, kshe zsh(mas não o shell Bourne), suporte:

for i; { echo "$i"; }

Todos (Bourne, bash, ksh, zsh) apoio:

for i
{ echo "$i";}

ksh93, bash, zshApoio:

for ((i=1;i<=3;i++)) { echo "$i"; }
Stéphane Chazelas
fonte
2
Como sempre, completa e resposta perfeita (com uma referência a zsh) ...
kiwy
2
Não é "estritamente necessário" em nenhum dos casos for; o comando pode ser finalizado por uma nova linha ou ponto e vírgula. Faz um pouco mais de sentido para if/ while(o primeiro com, em thenvez de do), mas, em princípio, aqueles poderiam ter omitido e exigido um subshell ou chaves para o uso (raro) de vários comandos. Suspeito que a verdadeira razão pela qual a concha Bourne o faça é porque a ALGOL o faz, e devemos estar felizes por donenão estar escrito od.
precisa saber é o seguinte
4
@ Random832: Isso porque odjá foi usado como o nome do programa Octal Dump.
User1024 31/08/16
8
tanta coisa aqui que eu não sabia. Obrigado!
Lightness Races in Orbit -
1
@mirabilos, for i doé Bourne e POSIX, mas não funcionará em algumas versões antigas do shell IIRC baseado em cinzas. for i in "$@"não funcionará no shell Bourne se $IFSnão contiver o caractere de espaço. for i<newline>doé realmente o mais portátil, se você precisar considerar sistemas BSD muito antigos. Veja in-ulm.de/~mascheck/various/bourne_args para obter detalhes
Stéphane Chazelas 1/16/16