Lời giải thích đúng đã được đưa ra bởi jsbillings và geekizard , nhưng hãy để tôi mở rộng thêm một chút.
Trong hầu hết các shell, bao gồm bash, mỗi bên của một đường ống chạy trong một lớp con, do đó, bất kỳ thay đổi nào trong trạng thái bên trong của shell (chẳng hạn như các biến cài đặt) vẫn bị giới hạn trong đoạn đường ống đó. Thông tin duy nhất bạn có thể nhận được từ một mạng con là những gì nó xuất ra (đến đầu ra tiêu chuẩn và các mô tả tệp khác) và mã thoát của nó (là một số trong khoảng từ 0 đến 255). Ví dụ: đoạn mã sau in 0:
a=0; a=1 | a=2; echo $a
Trong ksh (các biến thể có nguồn gốc từ mã AT & T, không phải các biến thể pdksh / mksh) và zsh, mục cuối cùng trong một đường ống được thực thi trong vỏ cha. (POSIX cho phép cả hai hành vi.) Vì vậy, đoạn trích trên in 2.
Một thành ngữ hữu ích là bao gồm sự tiếp tục của vòng lặp while (hoặc bất cứ điều gì bạn có ở phía bên phải của đường ống, nhưng một vòng lặp while thực sự phổ biến ở đây) trong đường ống:
cat junk | {
while read var ; do x=55 ; done
echo x=$x
}