Seu primeiro palpite estava certo, mas você usou um mau exemplo. Quando o shell lê o comando
foo=bar echo $foo
a primeira coisa que faz (ou, pelo menos, uma das primeiras coisas)
é procurar referências de variáveis (como $foo ) e avaliá-las.
Então processa o que resta da linha.
(Isso pode ser um pouco de simplificação excessiva;
veja bash(1) ou o Bash Reference Manual para detalhes.)
Então você tem o comando
echo (nothing)
executando com foo=bar ; mas é muito tarde; não resta mais nada para ver o valor de $foo .
Você pode demonstrar isso com a seguinte sequência:
$ foo=oldvalue
$ foo=bar echo "$foo"
oldvalue
Mas
foo=bar command
é o caminho a percorrer. Alguns exemplos que funcionam são:
foo=bar sh -c 'echo "$foo"'
e
foo=bar env
(Você pode querer canalizar isso através de grep foo .)
Eu acabei de notar a frase que você citou,
“Quando essas instruções de atribuição precedem um comando embutido no shell, por exemplo,…”,
sugerindo que comandos internos (como echo ) representam um caso especial.
É intuitivo (para mim, pelo menos) que esse "escopo de comando" que você está procurando
teria que trabalhar definindo uma variável de ambiente em um processo filho,
e não está claro como isso funcionaria para um comando interno, que não é executado em um processo filho.
Não há muitos comandos internos que acessam diretamente o ambiente,
e sua interação com variáveis shell é, às vezes, arcanizada.
Mas eu criei mais alguns exemplos que podem ser mais do que você procura:
foo=bar eval 'echo $foo'
exibirá "barra", porque a avaliação de $foo é adiada.
Ele é manipulado pelo comando eval (interno), em vez da passagem de análise inicial do shell.
Ou crie um arquivo de texto chamado (por exemplo) showme.sh .
Coloque um comando echo $foo (ou echo "$foo" ) nele e diga
foo=bar . showme.sh
Isto é provavelmente o que seu livro está falando quando diz:
“… O shell tem que acompanhar a ordem correta na qual resolver referências de variáveis….”
De alguma forma, o shell executa os comandos em showme.sh com foo igual a bar ,
e depois reverte para o valor anterior de foo (se houver)
quando voltar para sua entrada principal (o terminal).