พิจารณาคำสั่ง
eval false || echo ok
echo also ok
ปกติเราจะคาดหวังนี้จะดำเนินการfalseสาธารณูปโภคและเนื่องจากสถานะออกเป็นที่ไม่ใช่ศูนย์ไปแล้วดำเนินการและecho okecho also ok
ในทุก POSIX เหมือนเปลือกหอยที่ผมใช้ ( ksh93, zsh, bash, dash, OpenBSD kshและyash) นี้เป็นสิ่งที่เกิดขึ้น set -eแต่สิ่งที่ได้รับที่น่าสนใจถ้าเราเปิดใช้งาน
หากset -eมีผล OpenBSD ของshและkshเปลือกหอย (มาทั้งจากpdksh) evalจะยุติสคริปต์เมื่อการดำเนินการ ไม่มีเปลือกอื่นทำ
POSIX บอกว่าข้อผิดพลาดในยูทิลิตี้บิวด์อินพิเศษ (เช่นeval) ควรทำให้เชลล์ที่ไม่มีการโต้ตอบหยุดทำงาน ฉันไม่แน่ใจทั้งหมดว่าการดำเนินการfalseถือเป็น "ข้อผิดพลาด" (ถ้าเป็นเช่นนั้นจะเป็นอิสระจากset -eการใช้งาน)
วิธีแก้ปัญหานี้ดูเหมือนว่าจะใส่ไว้evalในเปลือกย่อย
( eval false ) || echo ok
echo also ok
คำถามคือว่าฉันคาดว่าจะต้องทำอย่างนั้นในสคริปต์เชลล์ที่ถูกต้อง POSIX หรือไม่หรือว่าเป็นข้อบกพร่องในเชลล์ของ OpenBSD หรือไม่ นอกจากนี้ "ความผิดพลาด" ในข้อความ POSIX ที่เชื่อมโยงกับด้านบนมีความหมายอย่างไร
ข้อมูลบิตพิเศษ: เชลล์ OpenBSD จะดำเนินการecho okทั้งที่มีและไม่มีset -e ในคำสั่ง
eval ! true || echo ok
รหัสเดิมของฉันดูเหมือน
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
ซึ่งจะไม่ส่งออกnot okด้วยการstring=falseใช้เปลือกหอย OpenBSD (มันจะยุติ) และฉันไม่แน่ใจว่ามันเป็นโดยการออกแบบโดยไม่ได้ตั้งใจหรือโดยความเข้าใจผิดหรืออย่างอื่น
eval falseจะยุติสคริปต์แม้ว่าจะเป็นส่วนหนึ่งของรายการ AND-OR หรือคำสั่งแบบมีเงื่อนไข? ฉันจะไม่
set -eมีการตั้งค่าหรือไม่ถ้านั่นเป็นพฤติกรรมที่ถูกต้อง ... ฉันยอมรับว่ามันสมเหตุสมผลที่จะไม่ยุติในคำสั่งแบบมีเงื่อนไข
set -eดังนั้น `() คือคำตอบ
eval falseสร้างสถานะที่ไม่ใช่ศูนย์ดังนั้นฉันคาดว่าset -eจะยุติสคริปต์ในตอนนั้น ในกรณีที่!set -eไม่ได้ใช้เป็น!คำสั่งตรวจสอบสถานะการออกอย่างชัดเจน