捕捉SIGKILL信号(kill -9)

-9 KILL (non-catchable, non-ignorable kill)
kill -9 is SIGKILL and Unix system by design doesn’t allow any script/program to trap SIGKILL due to security reasons. Otherwise any script can trap & ignore SIGKILL which will make impossible to terminate that script by OS.

kill -9会发送SIGKILL信号,程序一般来说不能捕捉,但是有时候我们我们希望程序被kill时,执行某些操作保存log等等

  • 启动主进程sh run.sh时,同时启动一个不依附于主进程的守护进程
  • 该守护进程监控sh run.sh是否结束了,如果结束则被触发,然后可以写一些“善后代码”,gracely exit
  • **切记: **直接执行 sh run.sh才有效,如果sh run.sh在另一个shell tmp.sh中然后执行了sh tmp.sh,这样的话,run.sh中的守护进程会依附于tmp.sh,当tmp被kill时它直接被kill了,根本无法守护run.sh

原始代码链接:
https://askubuntu.com/questions/832767/run-another-command-when-my-script-receives-sigkill-signal

#!/bin/bash

# Launch a sleeping child process that will be "waited" next
sleep infinity & PID=$!

# Trap "graceful" kills and use them to kill the sleeping child
trap "kill $PID" TERM

# Launch a subprocess not attached to this script that will trigger
# commands after its end
( sh -c "
    # Watch main script PID. Sleep duration can be ajusted 
    # depending on reaction speed you want
    while [ -e /proc/$$ ]; do sleep 3; done

    # Kill the infinite sleep if it's still running
    [ -e /proc/$PID ] && kill $PID

    # Commands to launch after any stop
    echo "Terminating"

" & )    

# Commands to launch before waiting
echo "Starting"

# Waiting for infinite sleep to end...
wait

# Commands to launch after graceful stop
echo "Graceful ending"

如果你有更特殊的需求,比如主进程sh run.sh中还有其他子进程不在主进程中,当主进程被kill -9时也想收到通知,同理可在守护进程中,发送信号给子进程,如果子进程需要接收SIGINT时,需要在run.sh中加set -m,因为默认情况下后台进程会忽略SIGINT

run.sh

#!/bin/bash
# Job control is enabled
# Send SIGINT to background tasks (if not, SIGINT will be ignored)
set -m
# Launch a child process of target task
sh A.sh  & PID=$!
# Launch a subprocess not attached to this script that will trigger commands after its end
( sh -c "
    # Watch main script PID. Sleep duration can be ajusted
    # depending on reaction speed you want
    while [ -e /proc/$$ ]; do sleep 1; done

    # Kill A if it's still running
    # kill -2: send SIGINT
    [ -e /proc/$PID ] && kill -2 $PID
" & )

# Waiting for A to end...
wait $PID
发布了104 篇原创文章 · 获赞 214 · 访问量 39万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章