เวิร์กสเตชันออนไลน์ของ OnWorks Linux และ Windows

โลโก้

ฟรีโฮสติ้งออนไลน์สำหรับเวิร์กสเตชัน

<ก่อนหน้านี้ | เนื้อหา | ถัดไป>

กับดัก

ในบทที่ 10 เราเห็นว่าโปรแกรมสามารถตอบสนองต่อสัญญาณได้อย่างไร เราสามารถเพิ่มความสามารถนี้ให้กับสคริปต์ของเราได้เช่นกัน แม้ว่าสคริปต์ที่เราเขียนมาจนถึงตอนนี้ยังไม่ต้องการความสามารถนี้ (เพราะมีเวลาดำเนินการสั้นมาก และไม่สร้างไฟล์ชั่วคราว) สคริปต์ที่ใหญ่กว่าและซับซ้อนกว่าอาจได้ประโยชน์จากการมีรูทีนการจัดการสัญญาณ

เมื่อเราออกแบบสคริปต์ที่มีขนาดใหญ่และซับซ้อน สิ่งสำคัญคือต้องพิจารณาว่าจะเกิดอะไรขึ้นหากผู้ใช้ออกจากระบบหรือปิดเครื่องคอมพิวเตอร์ในขณะที่สคริปต์กำลังทำงาน เมื่อเกิดเหตุการณ์ดังกล่าวขึ้น สัญญาณจะถูกส่งไปยังกระบวนการที่ได้รับผลกระทบทั้งหมด ในทางกลับกัน โปรแกรมที่เป็นตัวแทนของกระบวนการเหล่านั้นสามารถดำเนินการเพื่อให้แน่ใจว่ามีการยกเลิกโปรแกรมอย่างเหมาะสมและเป็นระเบียบ สมมติว่าเราเขียนสคริปต์ที่สร้างไฟล์ชั่วคราวระหว่างการดำเนินการ ในการออกแบบที่ดี เราจะให้สคริปต์ลบไฟล์เมื่อสคริปต์ทำงานเสร็จ นอกจากนี้ยังควรให้สคริปต์ลบไฟล์หากได้รับสัญญาณที่ระบุว่าโปรแกรมกำลังจะถูกยกเลิกก่อนเวลาอันควร

ทุบตี จัดให้มีกลไกเพื่อการนี้เรียกว่า a กับดัก. กับดักถูกนำไปใช้กับคำสั่ง buildin ที่มีชื่ออย่างเหมาะสม กับดัก. กับดัก ใช้ไวยากรณ์ต่อไปนี้:

กับดัก สัญญาณอาร์กิวเมนต์ [สัญญาณ... ]

ที่ไหน อาร์กิวเมนต์ เป็นสตริงที่จะอ่านและปฏิบัติเป็นคำสั่งและ สัญญาณ เป็นข้อกำหนดของสัญญาณที่จะทริกเกอร์การดำเนินการของคำสั่งที่ตีความ

นี่คือตัวอย่างง่ายๆ:



#! / bin / ทุบตี


# trap-demo: การสาธิตการจัดการสัญญาณอย่างง่าย

#! / bin / ทุบตี


# trap-demo: การสาธิตการจัดการสัญญาณอย่างง่าย


กับดัก "echo 'ฉันไม่สนใจคุณ'" SIGINT SIGTERM for i ใน {1..5}; ทำ

echo "Iteration $i of 5" sleep 5

ทำ

กับดัก "echo 'ฉันไม่สนใจคุณ'" SIGINT SIGTERM for i ใน {1..5}; ทำ

echo "Iteration $i of 5" sleep 5

ทำ


สคริปต์นี้กำหนดกับดักที่จะรัน an เสียงสะท้อน คำสั่งทุกครั้งที่ได้รับสัญญาณ SIG-INT หรือ SIGTERM ในขณะที่สคริปต์กำลังทำงาน การทำงานของโปรแกรมมีลักษณะเช่นนี้เมื่อผู้ใช้พยายามหยุดสคริปต์โดยกด Ctrl-c:


[me@linuxbox ~]$ กับดักสาธิต

ทำซ้ำ 1 จาก 5

ทำซ้ำ 2 จาก 5 ฉันไม่สนใจคุณ การทำซ้ำ 3 จาก 5 ฉันไม่สนใจคุณ ทำซ้ำ 4 จาก 5

ทำซ้ำ 5 จาก 5

[me@linuxbox ~]$ กับดักสาธิต

ทำซ้ำ 1 จาก 5

ทำซ้ำ 2 จาก 5 ฉันไม่สนใจคุณ การทำซ้ำ 3 จาก 5 ฉันไม่สนใจคุณ ทำซ้ำ 4 จาก 5

ทำซ้ำ 5 จาก 5


ดังที่เราเห็น ทุกครั้งที่ผู้ใช้พยายามขัดจังหวะโปรแกรม ข้อความจะถูกพิมพ์แทน

การสร้างสตริงเพื่อสร้างลำดับคำสั่งที่มีประโยชน์อาจทำได้ยาก ดังนั้นจึงเป็นเรื่องธรรมดาที่จะระบุฟังก์ชันเชลล์เป็นคำสั่ง ในตัวอย่างนี้ มีการระบุฟังก์ชันเชลล์แยกต่างหากสำหรับแต่ละสัญญาณที่จะจัดการ:



#! / bin / ทุบตี

# trap-demo2: การสาธิตการจัดการสัญญาณอย่างง่าย exit_on_signal_SIGINT () {

echo "สคริปต์ถูกขัดจังหวะ" 2>&1 ทางออก 0

}


exit_on_signal_SIGTERM () {

echo "สคริปต์ถูกยกเลิก" 2>&1 ทางออก 0

}


กับดัก exit_on_signal_SIGINT SIGINT กับดัก exit_on_signal_SIGTERM SIGTERM

#! / bin / ทุบตี

# trap-demo2: การสาธิตการจัดการสัญญาณอย่างง่าย exit_on_signal_SIGINT () {

echo "สคริปต์ถูกขัดจังหวะ" 2>&1 ทางออก 0

}


exit_on_signal_SIGTERM () {

echo "สคริปต์ถูกยกเลิก" 2>&1 ทางออก 0

}


กับดัก exit_on_signal_SIGINT SIGINT กับดัก exit_on_signal_SIGTERM SIGTERM



สำหรับฉันใน {1..5}; ทำ

echo "Iteration $i of 5" sleep 5

ทำ


สำหรับฉันใน {1..5}; ทำ

echo "Iteration $i of 5" sleep 5

ทำ


สคริปต์นี้มีคุณลักษณะสอง กับดัก คำสั่งหนึ่งคำสั่งสำหรับแต่ละสัญญาณ ในทางกลับกัน กับดักแต่ละอันจะระบุฟังก์ชันของเชลล์ที่จะดำเนินการเมื่อได้รับสัญญาณเฉพาะ สังเกตการรวมของ an ทางออก คำสั่งในแต่ละฟังก์ชั่นการจัดการสัญญาณ โดยไม่ต้อง ทางออกสคริปต์จะดำเนินการต่อหลังจากเสร็จสิ้นฟังก์ชัน

เมื่อผู้ใช้กด Ctrl-c ในระหว่างการเรียกใช้สคริปต์นี้ ผลลัพธ์จะมีลักษณะดังนี้:



[me@linuxbox ~]$ กับดัก demo2

ทำซ้ำ 1 จาก 5

การวนซ้ำ 2 จาก 5 สคริปต์ถูกขัดจังหวะ

[me@linuxbox ~]$ กับดัก demo2

ทำซ้ำ 1 จาก 5

การวนซ้ำ 2 จาก 5 สคริปต์ถูกขัดจังหวะ


ภาพ

ไฟล์ชั่วคราว

เหตุผลหนึ่งที่ตัวจัดการสัญญาณรวมอยู่ในสคริปต์คือการลบไฟล์ชั่วคราวที่สคริปต์อาจสร้างขึ้นเพื่อเก็บผลลัพธ์ระดับกลางระหว่างการดำเนินการ มีศิลปะบางอย่างในการตั้งชื่อไฟล์ชั่วคราว ตามเนื้อผ้า โปรแกรมบนระบบที่เหมือน Unix จะสร้างไฟล์ชั่วคราวใน / Tmp ไดเร็กทอรี ไดเร็กทอรีที่ใช้ร่วมกันซึ่งมีไว้สำหรับไฟล์ดังกล่าว อย่างไรก็ตาม เนื่องจากมีการแชร์ไดเร็กทอรี จึงทำให้เกิดปัญหาด้านความปลอดภัย โดยเฉพาะอย่างยิ่งสำหรับโปรแกรมที่ทำงานด้วยสิทธิ์ superuser นอกเหนือจากขั้นตอนที่ชัดเจนในการตั้งค่าการอนุญาตที่เหมาะสมสำหรับไฟล์ที่เปิดเผยต่อผู้ใช้ทุกคนของระบบ สิ่งสำคัญคือต้องให้ไฟล์ชั่วคราวที่คาดเดาชื่อไฟล์ไม่ได้ เพื่อหลีกเลี่ยงการหาช่องโหว่ที่เรียกว่า a การโจมตีการแข่งขันชั่วคราว. วิธีหนึ่งในการสร้างชื่อที่ไม่สามารถคาดเดาได้ (แต่ยังคงอธิบายได้) คือการทำสิ่งนี้:

tempfile=/tmp/$(ชื่อฐาน $0).$$.$RANDOM

สิ่งนี้จะสร้างชื่อไฟล์ที่ประกอบด้วยชื่อของโปรแกรม ตามด้วย ID กระบวนการ (PID) ตามด้วยจำนวนเต็มสุ่ม อย่างไรก็ตาม โปรดทราบว่า $รัน-ดอม ตัวแปรเชลล์จะคืนค่าในช่วง 1-32767 เท่านั้น ซึ่งไม่ใช่ช่วงที่กว้างมากในแง่ของคอมพิวเตอร์ ดังนั้นอินสแตนซ์ของตัวแปรเพียงตัวเดียวจึงไม่เพียงพอที่จะเอาชนะผู้โจมตีที่กำหนด



ภาพ

วิธีที่ดีกว่าคือการใช้ mktemp โปรแกรม (เพื่อไม่ให้สับสนกับ mktemp ฟังก์ชันไลบรารีมาตรฐาน) ให้ทั้งชื่อและสร้างไฟล์ชั่วคราว NS mk- อุณหภูมิ โปรแกรมยอมรับเทมเพลตเป็นอาร์กิวเมนต์ที่ใช้สร้างชื่อไฟล์ เทมเพลตควรมีชุดอักขระ "X" ซึ่งแทนที่ด้วยจำนวนตัวอักษรและตัวเลขแบบสุ่มที่เกี่ยวข้อง ยิ่งชุดอักขระ "X" ยาวขึ้น ชุดอักขระสุ่มก็จะยิ่งยาวขึ้น นี่คือตัวอย่าง:

tempfile=$(mktemp /tmp/foobar.$$.XXXXXXXXXX)

สิ่งนี้สร้างไฟล์ชั่วคราวและกำหนดชื่อให้กับตัวแปร เทมไฟล์. อักขระ "X" ในเทมเพลตจะถูกแทนที่ด้วยตัวอักษรและตัวเลขแบบสุ่ม เพื่อให้ชื่อไฟล์สุดท้าย (ซึ่งในตัวอย่างนี้ รวมค่าขยายของพารามิเตอร์พิเศษด้วย $$ เพื่อรับ PID) อาจเป็นดังนี้:

/tmp/foobar.6593.UOZuvM6654

สำหรับสคริปต์ที่ดำเนินการโดยผู้ใช้ทั่วไป อาจเป็นการดีที่จะหลีกเลี่ยงการใช้ / Tmp และสร้างไดเร็กทอรีสำหรับไฟล์ชั่วคราวภายในโฮมไดเร็กทอรีของผู้ใช้ โดยมีโค้ดดังนี้:

[[ -d $HOME/tmp ]] || mkdir $HOME/tmp


ระบบปฏิบัติการคลาวด์คอมพิวติ้งยอดนิยมที่ OnWorks: