A explicação correta já foi dada por jsbillings e geekosaur , mas deixe-me expandir um pouco.
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 definir variáveis) permanece confinada ao segmento de um pipeline. A única informação que você pode obter de um subshell é o que ele gera (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, o seguinte snippet imprime 0:
a=0; a=1 | a=2; echo $a
No ksh (as variantes derivadas do código AT&T, não nas variantes pdksh / mksh) e no zsh, o último item de um pipeline é executado no shell pai. (O POSIX permite os dois comportamentos.) Portanto, o trecho acima imprime 2.
Um idioma útil é incluir a continuação do loop while (ou o que você tiver no lado direito do pipeline, mas um loop while é realmente comum aqui) no pipeline:
cat junk | {
while read var ; do x=55 ; done
echo x=$x
}