ในเรื่องที่เกี่ยวกับ bash shell ฉันพบว่าวิธีที่ดีที่สุดที่จะจำได้คือการทำความเข้าใจกับสิ่งที่เกิดขึ้น
หากสิ่งที่คุณต้องการทำคือจดจำวิธีการรับคำสั่งที่ถูกต้องคุณอาจลอง
program > /results 2> /results
นั่นเป็นสิ่งที่ดีและชัดเจนว่าเกิดอะไรขึ้นและจดจำได้ง่าย กล่าวคือ
1
STDOUT กำลังจะไป /results
2
STDERR ก็จะตรงไปที่/results
ปัญหาคือสิ่งนี้ไม่ทำงานอย่างที่คุณคาดหวัง พิจารณาสิ่งต่อไปนี้:
ไฟล์: /tmp/poem.txt
the quick brown fox jumped over the lazy dog
และเรียกใช้คำสั่ง
grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results
แล้วก็
$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
lazy dog
เกิดอะไรขึ้นที่นี่?
ความเข้าใจของฉันคือการทุบตีการตั้งค่าการเปลี่ยนเส้นทางชี้ STDERR ไปยังไฟล์โดยตรง/tmp/results
และเนื่องจากลักษณะ>
ที่ทำ 2 สิ่ง
- โดยปกติแล้วจะสร้างไฟล์ใหม่ - ในกรณีนี้โอกาสผ่านไปแล้วเนื่องจากทุบตีย้ายไปที่รูทีนนี้ในเวลาที่สร้างเอาต์พุต
- แทรกตรงไปที่จุดเริ่มต้นของไฟล์ และไม่ได้ผนวกเช่น
>>
นั้น
ดังนั้นในกรณีนี้ STDERR แทรกโดยตรงในจุดเริ่มต้นของการ/tmp/results
เอาชนะเอาท์พุทของ STDOUT
หมายเหตุ: หากคุณเคย>>
ต่อท้ายคุณอาจไม่อยู่กับไวยากรณ์นี้
อย่างไรก็ตามเพื่อแก้ไขปัญหาที่คุณต้องการไม่ใช่เพื่อเปลี่ยนเส้นทาง STDERR ไปยังไฟล์โดยตรง แต่ควรรวมเอาท์พุทของ STDERR เข้าในสตรีม STDOUT ดังนั้นคุณจะไม่ได้รับการชนกัน
การใช้ตัวดำเนิน2>&1
การนั้นทำได้
grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1
&
ช่วยทุบตีจะแยกแยะออกจากไฟล์ชื่อ 1
และ1
อธิบายไฟล์
สำหรับฉันคำสั่ง2>&1
นั้นอธิบายอย่างชัดเจนว่าเกิดอะไรขึ้น - STDERR ถูกเปลี่ยนเส้นทางที่ STDOUT ตัวเอง - และจบลงด้วย/tmp/results
เพราะนั่นคือที่ STDOUT ชี้ (เกือบเป็นผลข้างเคียง)
ตรงข้ามกับคำแนะนำจำนวนมากที่อ้างว่าเป็นสิ่งที่2>&1
ส่ง STDERR ไปยังจุดที่ STDOUT เคยชี้ไป หากเป็นจริง - คุณจะยังคงมีปัญหาการเขียนทับ
ดูข้อมูลเพิ่มเติมได้ที่ - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection
program 1> /dev/null 2>/dev/null
เปลี่ยนเส้นทางทั้ง บางครั้งคุณต้องผสมstdout
และstderr
รวมกันเพื่อดูว่าเกิดอะไรขึ้นเช่นเอาท์พุทจากกระบวนการคอมไพล์ที่ซับซ้อนที่ถูกเปลี่ยนเส้นทางไปยังไฟล์ ในกรณีนี้ฉันไปจบด้วย googling