Andreas Veithen ชี้ให้เห็นว่าถ้าคุณไม่ต้องการกลับจากการโทร (เช่นในตัวอย่างของ OP) เพียงแค่เรียกผ่านexec
คำสั่งก็เพียงพอแล้ว ( @Stuart P. Bentley คำตอบของ ) มิฉะนั้น "ดั้งเดิม" trap 'kill $CHILDPID' TERM
(คำตอบของ @ cuonglm) เป็นการเริ่มต้น แต่การwait
โทรกลับจริง ๆ หลังจากตัวจัดการกับดักทำงานซึ่งยังคงเป็นก่อนที่กระบวนการลูกออกจริง ดังนั้นwait
ขอแนะนำให้โทร "พิเศษ" ( คำตอบของ @ user1463361 )
ขณะนี้เป็นการปรับปรุงมันยังคงมีสภาพการแข่งขันซึ่งหมายความว่ากระบวนการอาจไม่เคยออก (เว้นแต่ผู้ส่งสัญญาณลองส่งสัญญาณ TERM) หน้าต่างของช่องโหว่อยู่ระหว่างการลงทะเบียนกับตัวจัดการกับดักและการบันทึก PID ของเด็ก
ต่อไปนี้จะกำจัดจุดอ่อนนั้น (บรรจุอยู่ในฟังก์ชันเพื่อนำมาใช้ซ้ำ)
prep_term()
{
unset term_child_pid
unset term_kill_needed
trap 'handle_term' TERM INT
}
handle_term()
{
if [ "${term_child_pid}" ]; then
kill -TERM "${term_child_pid}" 2>/dev/null
else
term_kill_needed="yes"
fi
}
wait_term()
{
term_child_pid=$!
if [ "${term_kill_needed}" ]; then
kill -TERM "${term_child_pid}" 2>/dev/null
fi
wait ${term_child_pid}
trap - TERM INT
wait ${term_child_pid}
}
# EXAMPLE USAGE
prep_term
/bin/something &
wait_term