Você pediu respostas para duas perguntas:
-
Você solicitou uma explicação de por que seu código atual não produz o resultado esperado.
-
Você pediu a maneira correta de escrever seu código para que ele produza a saída esperada.
Olhando para o seu código, posso ver duas explicações prováveis sobre por que você escreveu seu código da seguinte maneira:
-
Pode haver alguma confusão sobre a sintaxe de um loop for .
-
Pode haver alguma pequena confusão sobre a ordem de avaliação no que é chamado de simples comando .
sintaxe for-loop
No primeiro caso, eu diria que você está perdendo um ponto-e-vírgula após a atribuição da variável. Se você quiser escrever seu loop for em uma única linha, será necessário colocar um ponto e vírgula após cada comando no corpo do loop. Tente isso:
for i in {1..5}; do x="${i}"; echo "$x"; done
Outra alternativa seria escrever o for-loop usando a sintaxe de várias linhas com novas linhas no lugar do ponto-e-vírgula:
for i in {1..5}
do
x="${i}"
echo "${x}"
done
Você também pode misturar e ponto-e-vírgulas e novas linhas, por exemplo:
for i in {1..5}; do
x="${i}"; echo "${x}"
done
avaliação de comandos simples
No segundo caso, eu diria que você provavelmente assumiu que a atribuição de variável no prólogo do comando (ou seja, a atribuição x="$i"
) ocorre antes da expansão da variável no corpo do comando (ou seja, a expansão de ${x}
em echo "${x}"
). Mas isso não é realmente o caso. Para verificar isso, podemos nos referir à página na expansão simples de comandos o Manual de Bash ou a subseção em comandos simples no Especificação de Posix . Ambas as referências incluem a seguinte passagem:
A "simple command" is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator.
When a given simple command is required to be executed (that is, when any conditional construct such as an AND-OR list or a case statement has not bypassed the simple command), the following expansions, assignments, and redirections shall all be performed from the beginning of the command text to the end:
The words that are recognized as variable assignments or redirections according to Shell Grammar Rules are saved for processing in steps 3 and 4.
The words that are not variable assignments or redirections shall be expanded. If any fields remain following their expansion, the first field shall be considered the command name and remaining fields are the arguments for the command.
Redirections shall be performed as described in Redirection.
Each variable assignment shall be expanded for tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal prior to assigning the value.
Observe que a etapa 2 é onde ocorre a expansão da variável no comando, mas a etapa 1 informa que as atribuições de variáveis são salvas até as etapas 3 e 4. Segue-se que a expressão echo "${x}"
é expandida para echo ""
antes da atribuição x="${i}"
ocorre. Isso explica por que você estava obtendo saída vazia.
Para uma discussão mais aprofundada sobre este tópico, consulte os seguintes posts: