เหตุใดการเปลี่ยนเส้นทาง STDERR ไปยัง / dev / null จึงทำเช่นนี้


28

สิ่งนี้ไม่สมเหตุสมผลสำหรับฉัน

wibble > /dev/null 2>&1

ฉันคิดว่ามันจะสมเหตุสมผลถ้ามันเป็นแบบนี้:

wibble 2>&1 > /dev/null

ในคำอื่น ๆ

Commands Output Sendall STDERRORS to STDOUT then SEND it all to /dev/null

ความคิดที่อยู่เบื้องหลังคำสั่งของการเปลี่ยนเส้นทางคำสั่งxxx > /dev/null 2>1คืออะไร?


6
คุณอาจพบว่าคำอธิบายนี้มีประโยชน์
rozcietrzewiacz

ขอบคุณ @rozcietzewiacz ที่จริง ๆ แล้วอธิบายคำถามของฉันอย่างแน่นอน
whoami

1
มีข้อความที่ยอดเยี่ยมอยู่ตรงกลางของหน้าในวิกิพีเดียของเกร็ก:“ ถ้าคุณยังสับสนอยู่ ณ จุดนี้อาจเป็นเพราะคุณเริ่มเข้าใจผิดเกี่ยวกับการทำงานของ FD และคุณไม่สามารถวางความเข้าใจผิดนั้นได้ ยัง ไม่ต้องกังวล - มันเป็นความเข้าใจผิดที่ธรรมดามากและคุณไม่ได้โดดเดี่ยว …หลายคนคิดว่า2>&1“ รวมกัน” หรือ“ ผูกมัดกัน” หรือ“ แต่งงาน” ทั้งสอง FD ดังนั้นการเปลี่ยนแปลงใด ๆ ที่ตามมาของพวกเขาจะกลายเป็นการเปลี่ยนแปลงต่อกัน นี่ไม่ใช่กรณีนี้”
G-Man กล่าวว่า 'Reinstate Monica'

คำตอบ:


40

การเปลี่ยนเส้นทางจะดำเนินการจากซ้ายไปขวา ถ้าคุณทำ

2>&1 1> /dev/null

การเปลี่ยนเส้นทางครั้งแรกทำให้stderrชี้ไปที่สตรีมที่stdoutชี้ไปในเวลานั้น (ซึ่งก็คือ tty ของคุณ) มันไม่ได้ทำให้นามแฝงของstderrstdout

จากนั้นstdoutจะถูกเปลี่ยนเส้นทางไปยังที่เก็บข้อมูลบิต การstdoutเปลี่ยนเส้นทางไม่ส่งผลต่อการstderrเปลี่ยนเส้นทางก่อนหน้า stderrยังคงหมายถึง tty ของคุณ

ดังนั้น:

ls file_that_doesnt_exist 2>&1 1> /dev/null

จะพิมพ์เฉพาะข้อความแสดงข้อผิดพลาดบนเครื่องเทอร์มินัลของคุณ

bashหน้าเอกสารประกอบการเปลี่ยนเส้นทางกล่าวถึงนี้อย่างชัดเจน:

โปรดทราบว่าลำดับการเปลี่ยนเส้นทางมีความสำคัญ ตัวอย่างเช่นคำสั่ง

          ls > dirlist 2>&1

นำทั้งเอาต์พุตมาตรฐานและข้อผิดพลาดมาตรฐานไปยังไฟล์ dirlist ขณะที่คำสั่ง

          ls 2>&1 > dirlist

นำเฉพาะมาตรฐานการส่งออกไปยังไฟล์ dirlist, เนื่องจากข้อผิดพลาดมาตรฐานถูกซ้ำจากมาตรฐานการส่งออกก่อนที่จะออกมาตรฐานได้รับการเปลี่ยนเส้นทางไปยัง dirlist


3
Yay แก้ปริศนาของฉัน ฉันยังคิดว่ามันมีเหตุผลที่สับสน แต่ฉันพบอีกส่วนหนึ่งในหน้าเดียวกันที่น่าสนใจ&>/dev/nullเทียบเท่ากับ semantically/dev/null 2>&1
whoami

1
ควรเน้นว่าหน้าที่คุณกำลังพูดถึงเป็นส่วนหนึ่งของคู่มืออ้างอิงBash มันเห็นได้ชัดว่าอธิบายทุบตี มีเปลือกหอยอื่น ๆ ในโลกที่แตกต่างจากการทุบตีมีและ&>และ>&(เมื่อไม่ได้ใช้ในบริบท2>&1หรือ>&2อื่น ๆ ) มีทุบตี-ISMS และไม่ได้มาตรฐาน ไม่ควรใช้ในเชลล์สคริปต์ที่คุณต้องการพกพา
G-Man กล่าวว่า 'Reinstate Monica'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.