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