A explicação correta já foi dada por jsbillings e geekosaur , mas deixe-me expandir um pouco sobre isso.
Na maioria dos shells, incluindo o bash, cada lado de um pipeline é executado em um subshell, portanto, qualquer alteração no estado interno do shell (como variáveis de configuração) permanece confinada a esse segmento de um pipeline. A única informação que você pode obter de um subshell é o que ele produz (para saída padrão e outros descritores de arquivo) e seu código de saída (que é um número entre 0 e 255). Por exemplo, as seguintes impressões de fragmentos 0:
a=0; a=1 | a=2; echo $a
Em ksh (as variantes derivadas do código AT & T, não variantes pdksh / mksh) e zsh, o último item em um pipeline é executado no shell pai. (POSIX permite ambos os comportamentos.) Então o trecho acima imprime 2.
Um idioma útil é incluir a continuação do loop while (ou qualquer coisa que você tenha no lado direito do pipeline, mas um loop while é comum aqui) no pipeline:
cat junk | {
while read var ; do x=55 ; done
echo x=$x
}