#!/bin/sh
echo "hello world" | read var1 var2
echo $var1
echo $var2
sản xuất không có đầu ra vì đường ống chạy mỗi thành phần của họ bên trong một subshell. Subshells kế thừa các bản sao các biến của trình bao của cha mẹ, thay vì chia sẻ chúng. Hãy thử điều này:
#!/bin/sh
foo="contents of shell variable foo"
echo $foo
(
echo $foo
foo="foo contents modified"
echo $foo
)
echo $foo
Dấu ngoặc xác định vùng mã được chạy trong một vỏ con và $ foo giữ lại giá trị ban đầu sau khi được sửa đổi bên trong chúng.
Bây giờ thử điều này:
#!/bin/sh
foo="contents of shell variable foo"
echo $foo
{
echo $foo
foo="foo contents modified"
echo $foo
}
echo $foo
Các niềng răng là thuần túy cho nhóm, không subshell được tạo ra, và $ foo biến đổi bên trong dấu ngoặc là như nhau $ foo biến đổi bên ngoài chúng.
Bây giờ thử điều này:
#!/bin/sh
echo "hello world" | {
read var1 var2
echo $var1
echo $var2
}
echo $var1
echo $var2
Bên trong dấu ngoặc, đọc BUILTIN tạo $ var1 và $ var2 đúng và bạn có thể thấy rằng họ nhận được lặp lại. Bên ngoài niềng răng, chúng không tồn tại nữa. Tất cả các mã trong niềng răng đã được chạy trong một subshell bởi vì nó là một thành phần của một đường ống.
Bạn có thể đặt số lượng mã tùy ý giữa các dấu ngoặc, vì vậy bạn có thể sử dụng công trình xây dựng từng khối này bất cứ khi nào bạn cần chạy một khối tập lệnh shell phân tích đầu ra của một thứ khác.
Điều này phụ thuộc vào sự lựa chọn của vỏ. Ksh93 được thiết kế để hạn chế chi phí quá trình.Nó cũng chạy phần tử cuối cùng của một đường ống * bên trong * quy trình vỏ gọi, do đó bảo toàn trạng thái. –
Bash 4.2 giới thiệu một tùy chọn để làm điều tương tự. Tắt điều khiển công việc ('set + m') và đặt tùy chọn' lastpipe' ('shopt -s lastpipe'). – chepner
Tôi sẽ xem xét điều đó. Cảm ơn! –