Đầu tiên, lưu ý rằng cú pháp để đóng là 5>&-
hoặc6<&-
, tùy thuộc vào việc mô tả tệp đang được đọc để viết hay để đọc. Dường như có một lỗi đánh máy hoặc định dạng trục trặc trong bài viết trên blog đó.
Đây là kịch bản nhận xét.
exec 5>/tmp/foo # open /tmp/foo for writing, on fd 5
exec 6</tmp/bar # open /tmp/bar for reading, on fd 6
cat <&6 | # call cat, with its standard input connected to
# what is currently fd 6, i.e., /tmp/bar
while read a; do #
echo $a >&5 # write to fd 5, i.e., /tmp/foo
done #
Không có đóng cửa ở đây. Bởi vì tất cả các đầu vào và đầu ra sẽ đến cùng một vị trí trong ví dụ đơn giản này, việc sử dụng các mô tả tệp bổ sung là không cần thiết. Bạn có thể viết
cat </tmp/bar |
while read a; do
echo $a
done >/tmp/foo
Sử dụng mô tả tệp rõ ràng trở nên hữu ích khi bạn muốn ghi vào nhiều tệp lần lượt. Ví dụ, hãy xem xét một tập lệnh xuất dữ liệu thành tệp đầu ra dữ liệu và ghi nhật ký dữ liệu vào tệp nhật ký và có thể cả các thông báo lỗi. Điều đó có nghĩa là ba kênh đầu ra: một cho dữ liệu, một cho nhật ký và một cho lỗi. Vì chỉ có hai mô tả tiêu chuẩn cho đầu ra, nên một phần ba là cần thiết. Bạn có thể gọi exec
để mở các tập tin đầu ra:
exec >data-file
exec 3>log-file
echo "first line of data"
echo "this is a log line" >&3
…
if something_bad_happens; then echo error message >&2; fi
exec >&- # close the data output file
echo "output file closed" >&3
Nhận xét về hiệu quả xuất hiện khi bạn có một chuyển hướng trong một vòng lặp, như thế này (giả sử tập tin trống để bắt đầu):
while …; do echo $a >>/tmp/bar; done
Ở mỗi lần lặp, chương trình sẽ mở ra /tmp/bar
, tìm đến cuối tệp, nối thêm một số dữ liệu và đóng tệp. Sẽ hiệu quả hơn khi mở tệp một lần và mãi mãi:
while …; do echo $a; done >/tmp/bar
Khi có nhiều chuyển hướng xảy ra vào các thời điểm khác nhau, việc gọi exec
để thực hiện chuyển hướng thay vì gói một khối trong chuyển hướng sẽ trở nên hữu ích.
exec >/tmp/bar
while …; do echo $a; done
Bạn sẽ tìm thấy một số ví dụio-redirection
khác về chuyển hướng bằng cách duyệt thẻ trên trang web này .