捕捉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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章