ในเรื่องที่เกี่ยวกับ bash shell ฉันพบว่าวิธีที่ดีที่สุดที่จะจำได้คือการทำความเข้าใจกับสิ่งที่เกิดขึ้น
หากสิ่งที่คุณต้องการทำคือจดจำวิธีการรับคำสั่งที่ถูกต้องคุณอาจลอง
program > /results 2> /results
นั่นเป็นสิ่งที่ดีและชัดเจนว่าเกิดอะไรขึ้นและจดจำได้ง่าย กล่าวคือ
1 STDOUT กำลังจะไป /results
2STDERR ก็จะตรงไปที่/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