วิธีเรียกใช้คำสั่งก่อนที่สคริปต์ Bash จะออก


119

หากสคริปต์ Bash มีset -eและคำสั่งในสคริปต์ส่งกลับข้อผิดพลาดฉันจะล้างข้อมูลก่อนที่สคริปต์จะออกได้อย่างไร

ตัวอย่างเช่น:

#!/bin/bash
set -e
mkdir /tmp/foo
# ... do stuff ...
rm -r /tmp/foo

ฉันจะแน่ใจได้อย่างไรว่า/tmp/fooถูกลบออกแม้ว่าคำสั่งใดคำสั่งหนึ่งจะ... do stuff ...ล้มเหลว

คำตอบ:


194

นี่คือตัวอย่างของการใช้กับดัก:

#!/bin/bash -e

function cleanup {
  echo "Removing /tmp/foo"
  rm  -r /tmp/foo
}

trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails

เอาท์พุท:

dbrown@luxury:~ $ sh traptest
t: line 9: asdffdsa: command not found
Removing /tmp/foo
dbrown@luxury:~ $

สังเกตว่าแม้ว่าบรรทัด asdffdsa จะล้มเหลว แต่การล้างข้อมูลก็ยังคงดำเนินการอยู่


11

จากbashmanpage (เกี่ยวกับบิวด์อิน):

trap [-lp] [[arg] sigspec ... ]
คำสั่ง arg จะถูกอ่านและดำเนินการเมื่อเชลล์ได้รับสัญญาณ sigspec

ดังนั้นตามที่ระบุไว้ในคำตอบของ Anon.ให้โทรหาtrapสคริปต์ก่อนเพื่อตั้งค่าตัวจัดการที่คุณต้องการใน ERR


เรียกใช้help trapเพื่อดูวิธีใช้ในตัว
Flimm

8

จากข้อมูลอ้างอิงสำหรับset:

-e

ออกทันทีหากคำสั่งธรรมดา (ดูหัวข้อ 3.2.1 คำสั่งง่ายๆ) ออกโดยมีสถานะไม่ใช่ศูนย์เว้นแต่คำสั่งที่ล้มเหลวเป็นส่วนหนึ่งของลูป until หรือ while ซึ่งเป็นส่วนหนึ่งของคำสั่ง if ซึ่งเป็นส่วนหนึ่งของ && หรือ || รายการหรือหากสถานะการส่งคืนของคำสั่งถูกกลับด้านโดยใช้! กับดักบน ERR หากตั้งค่าไว้จะถูกดำเนินการก่อนที่เชลล์จะออก

(เน้นของฉัน)


อาจคุ้มค่าที่จะเพิ่ม "-E" เมื่อใช้ "-e" โปรดดูvaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail
Max Barraclough

3

shรุ่นของ devguydavid ของคำตอบ

#!/bin/sh
set -e
cleanup() {
  echo "Removing /tmp/foo"
  rm  -r /tmp/foo
}
trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails

อ้างอิง: shellscript.sh


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