วิธีการระงับเอาต์พุตของคำสั่ง แต่แสดงว่าคำสั่ง exit code มีข้อผิดพลาดหรือไม่?
วิธีการระงับเอาต์พุตของคำสั่ง แต่แสดงว่าคำสั่ง exit code มีข้อผิดพลาดหรือไม่?
คำตอบ:
น่าเสียดายที่สมมติฐานที่stderrใช้สำหรับการส่งออกข้อผิดพลาดนั้นไม่ถูกต้องเสมอไป แต่stderrมักจะใช้สำหรับการใด ๆ และทุกโต้ตอบการส่งออกและการวินิจฉัยการส่งออกเช่นมีไว้สำหรับผู้ใช้ที่จะอ่านในการโต้ตอบพร้อมท์1 wgetและddเป็นตัวอย่างที่รู้จักกันดี
คำสั่งบางคำสั่งจะมีการตั้งค่าสถานะ (เช่น-quietหรือ-silent) เพื่อระงับเอาต์พุตที่ไม่ใช่ข้อผิดพลาด - อ่าน man page ของพวกเขาเพื่อดูว่ามีอยู่จริงหรือไม่
ระเบียบการประชุมอื่นที่เก็บบ่อยกว่าคือรหัสออก : โปรแกรมส่งคืนรหัสออกเมื่อออก โดยทั่วไป2รหัสทางออกของการ0ระบุความสำเร็จและรหัสการออกอื่น ๆ บ่งชี้ถึงข้อผิดพลาด
ด้วยbashคุณสามารถรับรหัสทางออกของคำสั่งสุดท้ายจาก$?ตัวแปร ในfishใช้$statusตัวแปร คุณสามารถไพพ์stderrไปที่ไฟล์ชั่วคราวและพิมพ์ได้ก็ต่อเมื่อเกิดข้อผิดพลาด ตัวอย่าง ( fish):
command 2>/tmp/outputbuffer
if $status
cat /tmp/outputbuffer
rm /tmp/outputbuffer
คุณยังสามารถใช้ทางลัดบางตัวได้หากคุณไม่ได้ใช้คำสั่ง chaining:
if command 2>/tmp/outputbuffer
cat /tmp/outputbuffer
rm /tmp/outputbuffer
หรือ:
command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;
นอกจากนี้คุณยังสามารถท่อไปยังบัฟเฟอร์เดียวกันโดยใช้stdout2>&1 >/tmp/outputbuffer
(หมายเหตุ: ฉันไม่รู้จริง ๆfishดังนั้นฉันจึงปรับแนวคิดกับสิ่งที่ฉันสามารถหาได้ในเอกสารประกอบของมันไวยากรณ์อาจผิดเล็กน้อยนอกจากนี้คุณสามารถใช้mktempเพื่อสร้างไฟล์ชั่วคราวที่ไม่ซ้ำกัน - เรียกใช้และบันทึก ชื่อไฟล์ในตัวแปร)
หากคุณต้องการเรียกใช้สิ่งทั้งหมดในพื้นหลังของเชลล์คุณยังใช้การโต้ตอบในเวลาเดียวกันคุณควรเขียนสคริปต์เพื่อจัดการกับการซ่อนเอาท์พุทและรันสคริปต์นั้นในเบื้องหลังด้วยเทคนิคมาตรฐาน ( fish) Heck คุณสามารถใส่ฟังก์ชันต่อไปนี้ใน~/.config/fish/config.fish:
function run-silent
set temp (mktemp)
if $argv 2>&1 >$temp
cat $temp
rm $temp
end
โทรด้วยrun-silent somecommand &(ที่ส่วนท้าย&ทำให้การเรียกใช้ในพื้นหลัง)
โปรดทราบว่านี่จะกลืนรหัสออกดั้งเดิมและจะถ่ายโอนข้อมูลทั้งสองstdoutและstderrในกรณีที่เกิดความล้มเหลว คุณสามารถปรับแต่งได้ตามความจำเป็น
1ไม่มีแม้แต่การรับประกันว่าข้อผิดพลาดจะไม่ปรากฏขึ้นstdout- บางโปรแกรมจะถ่ายโอนข้อมูลทั้งหมดที่นั่น!
2น่าเสียดายที่นี่ยังไม่เป็นเช่นนั้นเสมอ - รหัสทางออกถูกควบคุมโดยโปรแกรมอย่างสมบูรณ์และบางคนจะบ่งบอกถึงเงื่อนไขความสำเร็จที่มีการออกที่ไม่เป็นศูนย์ ตรวจสอบคู่มืออีกครั้ง
ยูทิลิตี้ Unix ส่งข้อความทั่วไปไปยังstdoutและข้อความแสดงข้อผิดพลาดไปstderrดังนั้นหากเราต้องการเห็นข้อความแสดงข้อผิดพลาดเท่านั้นมันจะเพียงพอที่จะระงับstdoutดังนั้นจะstderrได้รับผลลัพธ์ไปยังคอนโซลเท่านั้น
วิธีการทำเช่นนี้ (ในทั้งสองbashและfish) คือการผนวก>/dev/nullคำสั่ง ไปป์นี้ stdout สู่ความว่างเปล่า แต่ stderr (พร้อมข้อความแสดงข้อผิดพลาดของคุณ) ยังคงมาถึงคอนโซล
ตัวอย่างเช่น:
คำสั่งecho 1 >/dev/nullไม่พิมพ์อะไรเลยเนื่องจากstdoutเอาต์พุตปกติถูกระงับและไม่มีสิ่งใดถูกเขียนไปยัง stderr
คำสั่งman doesnotexist >/dev/nullพิมพ์ข้อความผิดพลาดเพราะเขียนข้อความข้อผิดพลาดในการmanstderr
สิ่งนี้จะรันคำสั่งในพื้นหลังและเขียนข้อผิดพลาดไปยังล็อกไฟล์โดยไม่สนใจเอาต์พุตปกติ
command > /dev/null 2> /tmp/example_error.log &