Правильные объяснения уже были даны jsbillings и geekosaur , но позвольте мне немного остановиться на этом.
В большинстве оболочек, включая bash, каждая сторона конвейера работает в подоболочке, поэтому любое изменение внутреннего состояния оболочки (например, установка переменных) остается ограниченным этим сегментом конвейера. Единственная информация, которую вы можете получить из подоболочки - это то, что она выводит (для стандартного вывода и других файловых дескрипторов) и ее код выхода (который находится в диапазоне от 0 до 255). Например, следующий фрагмент печатает 0:
a=0; a=1 | a=2; echo $a
В ksh (варианты, полученные из кода AT & T, а не в вариантах pdksh / mksh) и zsh, последний элемент конвейера выполняется в родительской оболочке. (POSIX допускает оба поведения.) Таким образом, фрагмент выше печатает 2.
Полезной идиомой является включение в конвейер продолжения цикла while (или того, что у вас есть в правой части конвейера, но цикл while на самом деле здесь обычен):
cat junk | {
while read var ; do x=55 ; done
echo x=$x
}