Mô tả tập tin & kịch bản shell


32

Tôi đang có một thời gian rất khó hiểu làm thế nào một người sử dụng mô tả tập tin trong các kịch bản shell.

Tôi biết những điều cơ bản như

exec 5 > /tmp/foo

Vì vậy, fd 5 được gắn vào foo để viết.

exec 6 < /tmp/bar

Giáo dục để đọc.

exec 5>&-

Cận cảnh fd.

Bây giờ cái này làm gì?

#!/bin/bash

exec 5 > /tmp/foo 
exec 6 < /tmp/bar 

cat <&6 | while read a
do
     echo $a >&5
done

Theo tôi hiểu &5đóng fd, vậy làm thế nào đầu ra vẫn được định hướng lại thành công sau mỗi cuộc gọi?

Đây là một bản sao mì ống từ: Đây

Nó tuyên bố sử dụng điều này đơn giản echo $a > filesẽ làm cho nó nhanh hơn nhiều, tuy nhiên tôi không hiểu. Tôi sẽ đánh giá cao bất kỳ liên kết đến hướng dẫn phong nha. Tôi quyền hạn google dường như đang thất bại tôi.

Câu trả lời:


44

Đầ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 .


1
Cú pháp để đóng mô tả tập tin thực sự làm điều tương tự.
user1338062
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.