วิธีการระงับเอาต์พุตของคำสั่ง แต่แสดงว่าคำสั่ง 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;
นอกจากนี้คุณยังสามารถท่อไปยังบัฟเฟอร์เดียวกันโดยใช้stdout
2>&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
พิมพ์ข้อความผิดพลาดเพราะเขียนข้อความข้อผิดพลาดในการman
stderr
สิ่งนี้จะรันคำสั่งในพื้นหลังและเขียนข้อผิดพลาดไปยังล็อกไฟล์โดยไม่สนใจเอาต์พุตปกติ
command > /dev/null 2> /tmp/example_error.log &