Menutup deskriptor file,> & - vs <& -

49

Dalam tutorial bash yang saya baca, dikatakan bahwa jika Anda membuka deskriptor file untuk dibaca, yaitu

exec 3< echolist

Maka Anda harus menutupnya seperti ini,

exec 3<&-

Namun, jika Anda membuka deskriptor file untuk menulis, itu harus ditutup seperti ini:

exec 3>&-

Namun ketika saya melihat di internet, saya melihat orang membuka file dan kemudian menutupnya dengan ini:

exec 3>&- 

CATATAN: ketika, menurut tutorial, mereka harus menggunakan exec 3<&1.

Jadi pertanyaan saya adalah, dapatkah semua deskriptor file ditutup melalui di exec n>&-mana n adalah nomor deskriptor file? Terlepas apakah itu dibuka untuk membaca, menulis, atau keduanya?

Jason
sumber
21
Satu-satunya perbedaan antara >&-dan <&-adalah fd default ketika tidak ditentukan ( >&-adalah 1>&-sementara <&-adalah 0<&-). Sama dengan x>&yyang x<&ykecuali saat xtidak disediakan.
Stéphane Chazelas

Jawaban:

48

Anda dapat menutup deskriptor file menggunakan keduanya <&-dan >&-, bashakan mem-parsing dua sintaks sebagai sama.

Dari file y.tab.c dalam bashkode sumber:

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);
cuonglm
sumber
2
Ini juga dapat digunakan pada <>deskriptor file.
CMCDragonkai
1
Tidak, itu tidak mungkin, tetapi seperti dalam 3>&-atau 3<&-tampaknya menutup deskripsi.
CMCDragonkai
1
Penutupan itu <>bisa dilakukan dengan cara yang sama.
CMCDragonkai
1
Saya tidak mengerti maksud Anda. Tolong beri
contoh./
1
Saya tidak berpikir itu yang saya maksudkan. Hanya saja deskriptor file tulis baca dapat ditutup menggunakan 3> & - dan 3 <& - juga.
CMCDragonkai
15

Sejauh yang saya bisa lihat, exec 3>&-dan exec 3<&-sama dan dapat digunakan pada deskriptor file apa pun, terlepas dari bagaimana dibuka. Menurut bagian 2.7.6 dan 2.7.5 definisi POSIX dari Bahasa Perintah Shell :

2.7.5 Menggandakan Penjelasan File Input

Operator pengalihan:

[n] <& kata

[...MENGGUNTING...]

Jika kata dievaluasi menjadi '-', deskriptor file n, atau input standar jika n tidak ditentukan, harus ditutup. Upaya untuk menutup deskriptor file yang tidak terbuka tidak akan menyebabkan kesalahan. Jika kata mengevaluasi sesuatu yang lain, perilaku tersebut tidak ditentukan.

2.7.6 Menggandakan Penjelasan File Keluaran

Operator pengalihan:

[n]> & kata

[...MENGGUNTING...]

Jika kata dievaluasi menjadi '-', deskriptor file n, atau output standar jika n tidak ditentukan, ditutup. Upaya untuk menutup deskriptor file yang tidak terbuka tidak akan menyebabkan kesalahan. Jika kata mengevaluasi sesuatu yang lain, perilaku tersebut tidak ditentukan.

Perhatikan bahwa tidak ada yang menentukan apa pun tentang bagaimana deskriptor file n dibuka pada awalnya. Ini sejalan dengan fakta bahwa close (2) tidak peduli bagaimana Anda membuka file.

Langkah cepat berikut ini:

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

versus ini:

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

menunjukkan bahwa dalam kedua kasus, Bash melakukan hal yang persis sama.

Dua Fakta yang Cukup Menarik

  • Bagian halaman bash man tentang duplikat deskriptor file tidak menyebutkan yang [n]>&-menutup deskriptor file.
  • Dalam kode Bash untuk menangani pengalihan (redir.c) Anda dapat menemukan ini:

    738      /* XXX - what to do with [N]<&$w- where w is unset or null?  ksh93
    739               closes N. */
Steven D
sumber
1
Halaman bash man menyebutkan penutupan, mengutip tautan Anda: Jika kata mengevaluasi ke '-', deskriptor file n ditutup.
pejantan
@studog Terima kasih telah memeriksa sumbernya! Saya pikir apa yang terjadi di sini adalah saya sedang melihat halaman manual lokal untuk Bash 3, dan kemudian ditautkan ke dokumentasi online, yaitu untuk Bash 4. Dalam dokumentasi Bash 3 yang lama, frasa tentang penutupan dihilangkan dari deskripsi [N]>&WORD: git .savannah.gnu.org / cgit / bash.git / tree / doc /…
Steven D
7

Contoh untuk pemahaman cuonglm tentang penutupan '<>' FD.

Ini dikutip dari Advanced Bash-Scripting Guide di 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.
DMW
sumber