ภาษาที่แน่นอนที่ใช้ในสเปคUNIX เดียวเพื่ออธิบายความหมายของset -e
คือ:
เมื่อเปิดใช้ตัวเลือกนี้หากคำสั่งอย่างง่ายล้มเหลวด้วยเหตุผลใดก็ตามที่ระบุไว้ในผลที่ตามมาของข้อผิดพลาดของเชลล์หรือส่งกลับค่าสถานะการออก> 0 และไม่ใช่ [คำสั่งแบบมีเงื่อนไขหรือไม่มีเงื่อนไข] เชลล์จะออกทันที
มีความคลุมเครือเป็นสิ่งที่เกิดขึ้นคือเมื่อคำสั่งดังกล่าวเกิดขึ้นในsubshell จากมุมมองที่ใช้งานได้จริงเชลล์ย่อยทั้งหมดสามารถทำได้คือออกและส่งคืนสถานะที่ไม่ใช่ศูนย์ไปยังเชลล์พาเรนต์ ไม่ว่าพาเรนต์เชลล์จะเปิดออกจะขึ้นอยู่กับว่าสถานะที่ไม่ใช่ศูนย์นี้แปลเป็นคำสั่งง่าย ๆ ที่ล้มเหลวในพาเรนต์เชลล์หรือไม่
หนึ่งในกรณีที่มีปัญหาดังกล่าวเป็นคนที่คุณพบ: สถานะกลับมาเป็นศูนย์จากแทนคำสั่ง เนื่องจากสถานะนี้ถูกละเว้นจึงไม่ทำให้เชลล์พาเรนต์ออก ในฐานะที่เป็นคุณได้ค้นพบแล้ววิธีการที่จะใช้สถานะทางออกเข้าบัญชีคือการใช้ทดแทนคำสั่งในการที่ง่ายที่ได้รับมอบหมายแล้วออกจากสถานะของงานจะออกจากสถานะของแทนคำสั่งสุดท้ายในการกำหนด (s)
โปรดทราบว่าสิ่งนี้จะดำเนินการตามที่ตั้งใจไว้เฉพาะในกรณีที่มีการทดแทนคำสั่งเดียวเนื่องจากสถานะการทดแทนครั้งล่าสุดเท่านั้นที่จะถูกนำมาพิจารณา ตัวอย่างเช่นคำสั่งต่อไปนี้สำเร็จ (ทั้งตามมาตรฐานและในการนำไปใช้ทุกครั้งที่ฉันเห็น):
a=$(false)$(echo foo)
กรณีที่จะดูก็คือsubshells อย่างชัดเจน(somecommand)
: ตามการตีความด้านบนเชลล์ย่อยอาจส่งคืนสถานะที่ไม่ใช่ศูนย์ แต่เนื่องจากนี่ไม่ใช่คำสั่งง่ายๆในเชลล์พาเรนต์เชลล์พาเรนต์ควรดำเนินการต่อ ในความเป็นจริงกระสุนทั้งหมดที่ฉันรู้จักทำให้ผู้ปกครองกลับมาที่จุดนี้ แม้ว่าสิ่งนี้จะมีประโยชน์ในหลาย ๆ กรณีเช่นในกรณี(cd /some/dir && somecommand)
ที่มีการใช้วงเล็บเพื่อให้การดำเนินการเช่นไดเรกทอรีปัจจุบันเปลี่ยนไปภายในเครื่อง แต่จะเป็นการละเมิดข้อกำหนดหากset -e
ถูกปิดใน subshell หรือถ้า subshell ส่งคืนสถานะที่ไม่ใช่ศูนย์ในลักษณะที่ จะไม่ยุติมันเช่นการใช้!
คำสั่งจริง ตัวอย่างเช่นทั้งหมดของ ash, bash, pdksh, ksh93 และ zsh exit โดยไม่แสดงfoo
ในตัวอย่างต่อไปนี้:
set -e; (set +e; false); echo "This should be displayed"
set -e; (! true); echo "This should be displayed"
ยังไม่มีคำสั่งง่ายๆที่ล้มเหลวในขณะที่set -e
มีผลบังคับใช้!
กรณีที่มีปัญหาประการที่สามคือองค์ประกอบในไปป์ไลน์ที่ไม่น่าสนใจ ในทางปฏิบัติเชลล์ทั้งหมดไม่สนใจความล้มเหลวขององค์ประกอบของไปป์ไลน์นอกเหนือจากที่ผ่านมาและแสดงพฤติกรรมหนึ่งในสองอย่างที่เกี่ยวข้องกับองค์ประกอบไปป์ไลน์สุดท้าย:
- ATT ksh และ zsh ซึ่งเรียกใช้งานองค์ประกอบสุดท้ายของไพพ์ไลน์ในพาเรนต์เชลล์ทำธุรกิจตามปกติ: หากคำสั่งง่าย ๆ ล้มเหลวในอิลิเมนต์สุดท้ายของไพพ์ไลน์เชลล์ดำเนินการคำสั่งนั้นซึ่งเกิดขึ้นเป็นเปลือกหลัก ทางออก
- กระสุนอื่น ๆ ประมาณพฤติกรรมโดยออกหากองค์ประกอบสุดท้ายของไปป์ไลน์คืนสถานะที่ไม่ใช่ศูนย์
เหมือนก่อนหน้าการปิดset -e
หรือใช้การปฏิเสธในองค์ประกอบสุดท้ายของไปป์ไลน์ทำให้เกิดการส่งคืนสถานะที่ไม่ใช่ศูนย์ในวิธีที่ไม่ควรยกเลิกเชลล์ เชลล์อื่นที่ไม่ใช่ ATT ksh และ zsh จะออกจาก
pipefail
ตัวเลือกของ Bash ทำให้ไปป์ไลน์เพื่อออกจากทันทีภายใต้set -e
องค์ประกอบใด ๆ ที่ส่งคืนสถานะที่ไม่ใช่ศูนย์
โปรดทราบว่าเป็นภาวะแทรกซ้อนเพิ่มเติมทุบตีปิดset -e
ใน subshells เว้นแต่ว่าจะอยู่ในโหมด POSIX ( set -o posix
หรือมีPOSIXLY_CORRECT
ในสภาพแวดล้อมเมื่อเริ่มทุบตี)
ทั้งหมดนี้แสดงให้เห็นว่าข้อมูลจำเพาะ POSIX โชคไม่ดีที่งานระบุ-e
ตัวเลือก โชคดีที่กระสุนที่มีอยู่ส่วนใหญ่มีความสอดคล้องในพฤติกรรมของพวกเขา