Bash script พร้อม `set -e` ไม่ได้หยุดอยู่ที่คำสั่ง` … && …… '


14

ฉันใช้set -eเพื่อหยุดทุบตีสคริปต์ในข้อผิดพลาดครั้งแรก

ทำงานได้ดีทั้งหมดเว้นแต่ฉันจะใช้คำสั่งด้วย&&:

$ cat script
set -e
cd not_existing_dir && echo 123
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
I'm running! =P
$

เมื่อเทียบกับ:

$ cat script
set -e
cd not_existing_dir
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
$

ตัวอย่างแรกยังคงเสียงก้องI'm running!แต่ตัวอย่างที่สองไม่ได้ ทำไมพวกเขาถึงประพฤติแตกต่างกัน

UPD คำถามที่คล้ายกัน: /programming/6930295/set-e-and-short-tests


คุณคาดหวังว่าจะเกิดอะไรขึ้นในตัวอย่างแรก
Flup

@Flup ฉันคาดว่าสคริปต์จะหยุดทำงานหลังจากcdคำสั่งไม่สำเร็จ
907th

1
ดูBashFAQ # 105สำหรับการสนทนาทั่วไปของสถานที่ที่set -eพฤติกรรมเป็นที่น่าแปลกใจ
Charles Duffy

คำตอบ:


10

นี่คือพฤติกรรมที่บันทึกไว้ หน้าคนทุบตี (1)พูดว่า, สำหรับset -e,

เชลล์ไม่ออกหากคำสั่งที่ล้มเหลวเป็นส่วนหนึ่งของรายการคำสั่งที่ตามหลังwhileหรือuntilคำหลักส่วนหนึ่งของการทดสอบทำตามคำifหรือelifคำสงวน ส่วนหนึ่งของคำสั่งใด ๆ ที่ดำเนินการใน&&หรือ||รายชื่อ ยกเว้นคำสั่งที่ตามหลังสุดท้าย&&หรือ||ใด ๆ คำสั่งในท่อ !แต่ที่ผ่านมาหรือถ้าค่าตอบแทนของคำสั่งจะถูกคว่ำด้วย
[เน้นเพิ่มแล้ว]

และข้อมูลจำเพาะภาษาคำสั่งเชลล์ POSIX ยืนยันว่านี่เป็นพฤติกรรมที่ถูกต้อง:

-eการตั้งค่าจะถูกละเว้นเมื่อมีการดำเนินรายการสารประกอบต่อไปwhile, until, ifหรือelifคำสงวน, ท่อเริ่มต้นด้วย!คำสงวนหรือคำสั่งของใด ๆ และหรือรายการอื่น ๆ กว่าที่ผ่านมา

และส่วนที่ 2.9.3 รายการของเอกสารที่กำหนด

รายการ AND-OR เป็นลำดับของหนึ่งหรือมากกว่าหนึ่งท่อคั่นด้วยตัวดำเนินการ " &&" และ " ||"


9

set -eตัวเลือกที่ไม่ได้มีผลในบางสถานการณ์และนี่คือการทำงานมาตรฐานและแบบพกพาทั่ว POSIX เปลือกสอดคล้อง


คำสั่งที่ล้มเหลวเป็นส่วนหนึ่งของไพพ์ไลน์:

false | true; echo printed

printedจะพิมพ์

และพิจารณาเฉพาะความล้มเหลวของไปป์ไลน์เท่านั้น:

true | false; echo 'not printed'

จะพิมพ์อะไร


ระยะคำสั่งล้มเหลวในรายการสารดังต่อไปนี้while, until, if, elifคำสงวน, ท่อเริ่มต้นด้วย!คำสงวนหรือคำสั่งใด ๆ ที่เป็นส่วนหนึ่งของ&&หรือ||รายการยกเว้นคนสุดท้าย:

false || true; echo printed

คำสั่งสุดท้ายล้มเหลวยังคงset -eได้รับผลกระทบ:

true && false; echo 'not printed'

subshellล้มเหลวในการใช้คำสั่งสารประกอบ:

(false; echo 'not printed') | cat -; echo printed

ขอขอบคุณ! การใช้echo "printed"และecho "not_printed"ในตัวอย่างของคุณจะชัดเจนขึ้น(แทนecho 1)
907th

3
โปรดทราบว่าset -eเป็นสาเหตุของการออก(false && true); echo not hereแต่ไม่ใช่ใน{ false && true; }; echo hereแม้ว่า YMMV ที่มีเชลล์แตกต่างกันและแม้กระทั่งเชลล์รุ่นเดียวกันต่างกัน ฉันจะไม่ติดต่อset -eกับเสาเรือและจะจัดการข้อผิดพลาดที่เหมาะสมแทน
Stéphane Chazelas

1

ฉันเดาว่าเป็นเงื่อนไขถ้าเป็นแล้วทั้งหมดประเมินเป็นจริง

ฉันเหนื่อย

set -e
if cd not_existing_dir
then  echo 123
fi
echo "I'm running! =P"

ใครให้

-bash: cd: not_existing_dir: No such file or directory
I'm running! =P

รหัสข้อผิดพลาดจะถูกจับถ้าเงื่อนไขดังนั้นทุบตีจะไม่ก่อให้เกิดการสิ้นสุดของการดำเนินการ


แต่ฉันไม่ได้ใช้if ... fi
907th

ฉันรู้ว่านี่เป็นนัยถ้า
Archemar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.