การดักจับและ subshells โดยนัยในเชลล์สคริปต์


12

สมมติว่าคุณมีเชลล์สคริปต์ที่รันโค้ดการล้างข้อมูลบางประเภทผ่านEXITกับดักเช่นนี้:

#!/bin/bash

mytrap () {
  echo "It's a trap!" >&2
}

trap mytrap exit

echo I am at the end of the script.

สิ่งนี้จะพิมพ์ออกมาIt's a trap!เมื่อสคริปต์ออก:

$ sh myscript
I am at the end of the script.
It's a trap!

คุณปรับเปลี่ยนสคริปต์เพื่อเพิ่มฟังก์ชั่นที่สร้างผลลัพธ์บางอย่างที่ได้รับการไพพ์ไปยังคำสั่งอื่นในท้ายที่สุดดังนี้:

#!/bin/bash

mytrap () {
  echo "It's a trap!" >&2
}

myfunc () {
  echo "I've got a bad feeling about this..."
}

trap mytrap exit

myfunc | cat > /dev/null

echo I am at the end of the script.

เนื่องจากไปป์รหัสในmyfuncจะทำงานใน subshell ... และ subshells ไม่ปรากฏว่าสืบทอดการtrapทำงานของพาเรนต์ซึ่งหมายความว่าหากคุณดำเนินการใด ๆ ที่นี่ซึ่งควรจะล้างข้อมูลด้วยรหัสกับดักที่ชนะ ' ไม่เกิดขึ้น

ดังนั้นคุณลองสิ่งนี้:

myfunc () {
  trap mytrap EXIT
  echo "I've got a bad feeling about this..."
}

และมันยังคงไม่สามารถทริกเกอร์mytrapเมื่อออกจาก subshell ปรากฎว่าคุณต้องมีความชัดเจนexitเช่นนี้:

myfunc () {
  trap mytrap EXIT
  echo "I've got a bad feeling about this..."
  exit
}

ด้วยโค้ดด้านบนmytrapจะทริกเกอร์อย่างเหมาะสมเมื่อออกจาก subshell:

$ sh myscript 
It's a trap!
I am at the end of the script.
It's a trap!

นั่นเป็นพฤติกรรมที่คาดหวังหรือไม่? ฉันรู้สึกประหลาดใจกับหลายสิ่งที่นี่:

  • trap การตั้งค่าไม่ได้รับการสืบทอดโดย subshells
  • การออกโดยปริยายจากเชลล์ย่อยไม่ปรากฏขึ้นเพื่อเรียกEXIT กับดัก

คำตอบ:


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