Bởi vì tôi yêu nó, tôi muốn bỏ một ghi chú. Tôi tìm thấy chủ đề này, bởi vì tôi phải viết lại một tập lệnh sh cũ để tương thích POSIX. Điều này về cơ bản có nghĩa là phá vỡ vấn đề đường ống / vỏ con được giới thiệu bởi POSIX bằng cách viết lại mã như thế này:
some_command | read a b c
vào:
read a b c << EOF
$(some_command)
EOF
Và mã như thế này:
some_command |
while read a b c; do
# something
done
vào:
while read a b c; do
# something
done << EOF
$(some_command)
EOF
Nhưng cái sau không hành xử giống nhau trên đầu vào trống. Với ký hiệu cũ, vòng lặp while không được nhập vào đầu vào trống, nhưng trong ký hiệu POSIX thì có! Tôi nghĩ rằng đó là do dòng mới trước EOF, không thể bị loại bỏ. Mã POSIX hoạt động giống như ký hiệu cũ trông như thế này:
while read a b c; do
case $a in ("") break; esac
# something
done << EOF
$(some_command)
EOF
Trong hầu hết các trường hợp, điều này là đủ tốt. Nhưng thật không may, điều này vẫn hoạt động không chính xác như ký hiệu cũ nếu some_command in một dòng trống. Trong ký hiệu cũ, phần thân được thực thi và trong ký hiệu POSIX, chúng ta ngắt trước phần thân.
Một cách tiếp cận để khắc phục điều này có thể trông như thế này:
while read a b c; do
case $a in ("something_guaranteed_not_to_be_printed_by_some_command") break; esac
# something
done << EOF
$(some_command)
echo "something_guaranteed_not_to_be_printed_by_some_command"
EOF