การปิดไฟล์ descriptor,> & - vs <& -


49

ในการกวดวิชาทุบตีฉันอ่านมันบอกว่าถ้าคุณเปิดไฟล์อธิบายสำหรับการอ่านคือ

exec 3< echolist

จากนั้นคุณต้องปิดมันแบบนี้

exec 3<&-

อย่างไรก็ตามหากคุณเปิดไฟล์ descriptor เพื่อทำการเขียนจะต้องปิดดังนี้:

exec 3>&-

แต่เมื่อฉันดูบนอินเทอร์เน็ตฉันเห็นผู้คนกำลังเปิดไฟล์แล้วปิดด้วย:

exec 3>&- 

หมายเหตุ:exec 3<&1เมื่อตามกวดวิชาที่พวกเขาควรจะใช้

ดังนั้นคำถามของฉันคือตัวอธิบายไฟล์ทั้งหมดสามารถปิดได้โดยexec n>&-ที่ n คือหมายเลขตัวอธิบายไฟล์หรือไม่ ไม่ว่าจะเปิดอ่านหนังสือเขียนหรือทั้งสองอย่าง


21
ข้อแตกต่างระหว่าง>&-และ<&-เป็นค่าเริ่มต้น fd เมื่อไม่ได้ระบุ ( >&-คือ1>&-ในขณะที่<&-เป็น0<&-) เหมือนกันx>&yซึ่งเหมือนกันx<&yยกเว้นเมื่อxไม่ได้จัดเตรียมไว้ให้
Stéphane Chazelas

คำตอบ:


48

คุณสามารถปิดอธิบายไฟล์โดยใช้ทั้ง<&-และ>&-, bashจะแยกสองไวยากรณ์เป็นเดียวกัน

จากไฟล์y.tab.cในbashซอร์สโค้ด:

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
สามารถใช้กับ<>ตัวอธิบายไฟล์ได้เช่นกัน
CMCDragonkai

1
ไม่เป็นไปไม่ได้ แต่เป็นใน3>&-หรือ3<&-ดูเหมือนจะปิด descriptor
CMCDragonkai

1
การปิด<>นั้นสามารถทำได้ผ่านวิธีเดียวกัน
CMCDragonkai

1
ฉันไม่สามารถรับสิ่งที่คุณหมายถึง โปรดยกตัวอย่าง. /
cuonglm

1
ฉันไม่คิดว่านั่นคือสิ่งที่ฉันหมายถึง เพียงแค่ตัวอธิบายไฟล์อ่านเขียน aa สามารถปิดได้โดยใช้ 3> & - และ 3 <& - เช่นกัน
CMCDragonkai

15

เท่าที่ฉันเห็นexec 3>&-และexec 3<&-เหมือนกันและสามารถใช้กับตัวอธิบายไฟล์ใด ๆ ไม่ว่าจะเปิดอย่างไร ตามส่วน 2.7.6 และ 2.7.5 ของการกำหนด POSIX ของภาษาคำสั่งเชลล์ :

2.7.5 การทำซ้ำตัวบ่งชี้ไฟล์อินพุต

ผู้ประกอบการเปลี่ยนเส้นทาง:

[N] <& คำ

[ ... SNIP ... ]

หาก word ประเมินค่าเป็น '-' ไฟล์ descriptor n หรืออินพุตมาตรฐานหากไม่ได้ระบุ n จะต้องปิด ความพยายามในการปิดไฟล์ descriptor ที่ไม่เปิดจะไม่ถือเป็นข้อผิดพลาด หากคำประเมินเป็นอย่างอื่นพฤติกรรมจะไม่ได้รับการกำหนด

2.7.6 การทำซ้ำ Descriptor ไฟล์เอาต์พุต

ผู้ประกอบการเปลี่ยนเส้นทาง:

[N]> & คำ

[ ... SNIP ... ]

หาก word ประเมินค่าเป็น '-' ไฟล์ descriptor n หรือเอาต์พุตมาตรฐานหากไม่ได้ระบุ n จะถูกปิด ความพยายามในการปิดไฟล์ descriptor ที่ไม่เปิดจะไม่ถือเป็นข้อผิดพลาด หากคำประเมินเป็นอย่างอื่นพฤติกรรมจะไม่ได้รับการกำหนด

โปรดทราบว่าไม่ได้ระบุอะไรเกี่ยวกับวิธีการเปิดไฟล์ descriptor n สิ่งนี้สอดคล้องกับความจริงที่ว่าclose (2)ไม่สนใจว่าคุณจะเปิดไฟล์อย่างไร

strace อย่างรวดเร็วต่อไปนี้:

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

เมื่อเทียบกับสิ่งนี้:

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

แสดงให้เห็นว่าในทั้งสองกรณี Bash ทำสิ่งเดียวกัน

ข้อเท็จจริงที่น่าสนใจสองประการ


1
หน้าคนทุบตีกล่าวถึงปิดการอ้างอิงลิงค์ของคุณ: หากคำประเมินเป็น '-' ตัวอธิบายไฟล์ n ถูกปิด
studog

@ studog ขอบคุณสำหรับการตรวจสอบแหล่งที่มา! ฉันคิดว่าสิ่งที่เกิดขึ้นที่นี่คือฉันกำลังดู manpage ท้องถิ่นสำหรับ Bash 3 แล้วเชื่อมโยงกับเอกสารออนไลน์ซึ่งสำหรับ Bash 4 ในเอกสาร Bash 3 เก่าวลีเกี่ยวกับการปิดถูกละเว้นจากคำอธิบายของ[N]>&WORD: git .savannah.gnu.org / cgit / bash.git / tree / doc / …
Steven D

7

ตัวอย่างสำหรับความเข้าใจของ cuonglm เกี่ยวกับการปิด '<>' FD

สิ่งนี้อ้างถึงจากคู่มือการใช้สคริปต์การทุบตีขั้นสูงที่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.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.