Đóng mô tả tệp,> & - vs <& -


49

Trong hướng dẫn bash tôi đang đọc, nó nói rằng nếu bạn mở một mô tả tệp để đọc, tức là

exec 3< echolist

Sau đó, bạn phải đóng nó như thế này,

exec 3<&-

Tuy nhiên, nếu bạn mở một mô tả tập tin để viết, nó phải được đóng lại như thế này:

exec 3>&-

Tuy nhiên, khi tôi tìm trên internet, tôi thấy mọi người mở tập tin và sau đó đóng chúng lại bằng cái này:

exec 3>&- 

LƯU Ý: khi nào, theo hướng dẫn, họ nên sử dụng exec 3<&1.

Vì vậy, câu hỏi của tôi là, tất cả các mô tả tập tin có thể được đóng thông qua exec n>&-n là số mô tả tập tin? Bất kể nếu nó được mở để đọc, viết, hoặc cả hai?


21
Sự khác biệt duy nhất giữa >&-<&-là fd mặc định khi không xác định ( >&-1>&-trong khi <&-0<&-). Tương x>&ytự như vậy, x<&yngoại trừ khi xkhông được cung cấp.
Stéphane Chazelas

Câu trả lời:


48

Bạn có thể đóng bộ mô tả tệp bằng cả hai <&->&-, bashsẽ phân tích hai cú pháp như nhau.

Từ tệp y.tab.c trong bashmã nguồn:

5385   /* Hack <&- (close stdin) case.  Also <&N- (dup and close). */                
5386   if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
5387     return (character);

2
Điều này có thể được sử dụng trên <>mô tả tập tin quá.
CMCDragonkai 17/2/2016

1
Không có điều đó là không thể, nhưng như trong 3>&-hoặc 3<&-xuất hiện để đóng mô tả.
CMCDragonkai 17/2/2016

1
Việc đóng cửa đó <>có thể được thực hiện thông qua các cách tương tự.
CMCDragonkai 17/2/2016

1
Tôi không thể hiểu ý bạn. Xin cho một
ví dụ

1
Tôi không nghĩ đó là những gì tôi muốn nói. Chỉ cần aa đọc mô tả tập tin ghi có thể được đóng bằng cách sử dụng 3> & - và 3 <& -.
CMCDragonkai

15

Theo như tôi thấy, exec 3>&-exec 3<&-đều giống nhau và có thể được sử dụng trên bất kỳ mô tả tập tin, bất kể như thế nào nó được mở ra. Theo các phần 2.7.6 và 2.7.5 của định nghĩa POSIX của Ngôn ngữ lệnh Shell :

2.7.5 Sao chép bộ mô tả tệp đầu vào

Toán tử chuyển hướng:

[n] <& từ

[... SNIP ...]

Nếu từ ước tính thành '-', mô tả tệp n hoặc đầu vào tiêu chuẩn nếu n không được chỉ định, sẽ bị đóng. Nỗ lực đóng một bộ mô tả tệp không mở sẽ không cấu thành lỗi. Nếu từ đánh giá đến một cái gì đó khác, hành vi là không xác định.

2.7.6 Sao chép bộ mô tả tệp đầu ra

Toán tử chuyển hướng:

[n]> & từ

[... SNIP ...]

Nếu từ ước tính thành '-', mô tả tệp n hoặc đầu ra tiêu chuẩn nếu n không được chỉ định, sẽ bị đóng. Nỗ lực đóng một bộ mô tả tệp không mở sẽ không cấu thành lỗi. Nếu từ đánh giá đến một cái gì đó khác, hành vi là không xác định.

Lưu ý rằng không chỉ định bất cứ điều gì về cách mô tả tập tin n đã được mở ban đầu. Điều này phù hợp với thực tế là đóng (2) không quan tâm đến cách bạn mở tệp.

Một bước nhanh chóng sau đây:

exec 3< /etc/passwd
exec 4> foo
exec 3<&-
exec 4<&-

so với điều này:

exec 3< /etc/passwd
exec 4> foo
exec 3<&-
exec 4>&-

cho thấy trong cả hai trường hợp, Bash đều thực hiện chính xác điều tương tự.

Hai sự thật thú vị

  • Phần trang bash man về sao chép mô tả tệp không đề cập đến việc [n]>&-đóng mô tả tệp.
  • Trong mã Bash để xử lý các chuyển hướng (redir.c), bạn có thể tìm thấy điều này:

    738      /* XXX - what to do with [N]<&$w- where w is unset or null?  ksh93
    739               closes N. */

1
Trang bash man đã đề cập đến việc đóng, trích dẫn liên kết của bạn: Nếu từ ước tính thành '-', mô tả tệp n bị đóng.
studog

@studog Cảm ơn bạn đã kiểm tra nguồn! Tôi nghĩ những gì đã xảy ra ở đây là tôi đang xem một trang web địa phương cho Bash 3, và sau đó được liên kết với tài liệu trực tuyến dành cho Bash 4. Trong tài liệu cũ của Bash 3, cụm từ về việc đóng cửa đã bị bỏ qua trong phần mô tả về [N]>&WORD: git .savannah.gnu.org / cgit / bash.git / cây / doc / Sự
Steven D

7

Một ví dụ cho sự hiểu biết của cuonglm về việc đóng một '<>' FD.

Điều này được trích dẫn từ Hướng dẫn Bash-Scripting nâng cao tại http://tldp.org/LDP/abs/html/io-redirection.html

[j]<>filename
  #  Open file "filename" for reading and writing,
  #+ and assign file descriptor "j" to it.
  #  If "filename" does not exist, create it.
  #  If file descriptor "j" is not specified, default to fd 0, stdin.
  #
  #  An application of this is writing at a specified place in a file. 
  echo 1234567890 > File    # Write string to "File".
  exec 3<> File             # Open "File" and assign fd 3 to it.
  read -n 4 <&3             # Read only 4 characters.
  echo -n . >&3             # Write a decimal point there.
  exec 3>&-                 # Close fd 3.
  cat File                  # ==> 1234.67890
  #  Random access, by golly.
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.