เมื่อใดที่จะใช้การเปลี่ยนเส้นทางไปยัง stderr ในเชลล์สคริปต์


15

ฉันรู้ว่าโปรแกรมอรรถประโยชน์ที่ทำงานได้ดีเช่นข้อความgrep "ปกติ" ไปยัง stdout และข้อความแสดงข้อผิดพลาดไปยัง stderr

$ grep '^foo' file1 file2
file1:foo
grep: file2: No such file or directory

เมื่อฉันเขียนเชลล์สคริปท์ตัวเองฉันมักจะพบว่ามันยากที่จะตัดสินใจว่าเอาต์พุตใดและข้อความใดที่ฉันควรแสดงบน stderr หรือถ้าฉันควรจะใส่ใจ

ฉันต้องการทราบเกี่ยวกับแนวปฏิบัติที่ดี: เมื่อใดที่มีการเปลี่ยนเส้นทางข้อความไปยัง stderr ที่ถูกเรียกร้องและสมเหตุสมผลและเมื่อใด

"ขึ้นอยู่กับ" แน่นอน แต่คุณมีความเข้าใจที่จะช่วยฉันตัดสินใจเหล่านี้หรือไม่

เพื่อให้คำถามอัตนัยนี้สอดคล้องกับรูปแบบฉันต้องการสนับสนุนคำตอบที่ตอบว่า "ทำไม" และได้รับการแจ้งจากประสบการณ์และหากได้รับการสนับสนุนจากข้อเท็จจริง


@rush อธิบายอย่างสมบูรณ์ ฉันมักจะพิมพ์รายงานความคืบหน้าไปยัง stderr สำหรับสคริปต์ยาว
terdon

คำตอบ:


12

เมื่อฉันเขียนเชลล์สคริปท์ตัวเองฉันมักจะพบว่ามันยากที่จะตัดสินใจว่าเอาต์พุตใดและข้อความใดที่ฉันควรแสดงบน stderr หรือถ้าฉันควรจะใส่ใจ

ความเงียบเป็นสีทอง เอาท์พุทถ้าทุกอย่างเรียบร้อยดี

ฉันต้องการทราบเกี่ยวกับแนวปฏิบัติที่ดี: เมื่อใดที่มีการเปลี่ยนเส้นทางข้อความไปยัง stderr ที่ถูกเรียกร้องและสมเหตุสมผลและเมื่อใด

วิธีที่ง่ายที่สุดในการแยก stderr ออกจาก stdout: แค่คิดเอาท์พุทสคริปต์ทั้งหมดของคุณจะถูกเปลี่ยนเส้นทางไปยังคำสั่งอื่นผ่านไพพ์ ในกรณีดังกล่าวคุณควรเก็บการแจ้งเตือนทั้งหมดไว้ใน stderr เนื่องจากข้อมูลที่ไม่คาดคิดใน stdout อาจทำให้ลำดับของไพพ์แตก

นอกจากนี้บางครั้งในท่อเช่นนี้:

command1 | while read line ; do command2 ; done | command3

คุณต้องส่งบางสิ่งจากcommand2ไปยังผู้ใช้งานเอาท์พุท วิธีที่ง่ายที่สุดโดยไม่มีไฟล์ชั่วคราวคือ stderr


ขอบคุณสำหรับแนวคิด "ลองนึกภาพท่อ" บางครั้งฉันปรับใช้สคริปต์ที่ไม่ทำอะไรเลยยกเว้น "แจ้งเตือน" ( echoตัวแปรบางตัวแสดงสิ่งที่ทำไปแล้วแสดงความคืบหน้า) ฉันลังเลที่จะวางทุกอย่างบน stderr เนื่องจากข้อความบันทึกเหล่านี้เป็นสคริปต์ทั้งหมดที่จะส่งออก ฉันไม่แน่ใจว่าจะใช้แนวคิดไพพ์ในสถานการณ์เหล่านี้ได้อย่างไร
glts

1
@glts โปรแกรมได้รับการแก้ไขและปรับปรุงอยู่เสมอ แม้ว่าสคริปต์ที่คุณพูดถึงจะไม่ส่งออกข้อมูลใด ๆ ในตอนนี้สคริปต์เหล่านั้นอาจใช้ในภายหลังหรือคุณอาจใช้เป็นจุดเริ่มต้นสำหรับสคริปต์อื่น ๆ หากคุณทำตามการประชุมเพื่อเริ่มต้นคุณจะได้รับความประหลาดใจน้อยลงในภายหลัง OTOH ถ้าคุณต้องการบันทึกผลลัพธ์ไปยังไฟล์คุณจะต้องเปลี่ยนเส้นทาง stderr ดังนั้นมันจึงเป็นการแลกเปลี่ยนที่ไม่เหมือนใคร
Joe

+1 การถอดความอีกครั้ง: ตรวจสอบให้แน่ใจว่า stdout สามารถอ่านด้วยเครื่องได้เสมอหรืออย่างน้อยก็มีข้อมูลที่เป็นประโยชน์ในรูปแบบที่สอดคล้องกัน
tripleee

2

โดยทั่วไปฉันเขียนทุกอย่างที่เกี่ยวข้องกับการทำงานของแอปพลิเคชันstderrซึ่งstdoutสงวนไว้สำหรับข้อมูล

catลองนึกภาพการประยุกต์ใช้เช่น เมื่อคุณใช้เพื่ออ่านอินพุตและส่งต่อไปยังแอปพลิเคชันอื่น (ผ่านทางไพพ์) คุณไม่ต้องการให้เอาต์พุตถูกทิ้งขยะด้วยข้อความสถานะ

ทุกอย่างที่อาจเป็นที่น่าสนใจสำหรับแอปพลิเคชันอื่นหรือตัวประมวลผลstdoutภายหลังจากแอปพลิเคชันของฉันกำลังจะเกิดstderrขึ้น


0

ความชอบส่วนบุคคลของฉันคือการส่งข้อความผิดพลาดและข้อยกเว้นและข้อความที่ให้ข้อมูลstderr stdoutIMO stderrเป็นข้อยกเว้นใด ๆ และด้วยเหตุนี้การประชุมของฉัน

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