พิจารณาคำสั่ง
eval false || echo ok
echo also ok
ปกติเราจะคาดหวังนี้จะดำเนินการfalse
สาธารณูปโภคและเนื่องจากสถานะออกเป็นที่ไม่ใช่ศูนย์ไปแล้วดำเนินการและecho ok
echo 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
ไม่ได้ใช้เป็น!
คำสั่งตรวจสอบสถานะการออกอย่างชัดเจน