Suppose I run a script
$ nohup ./myscript </dev/null >/dev/null 2>&1 &
and then kill it
$ pkill myscript
How can my script be designed so that when it receives the SIGKILL signal, another command is run?
Suppose I run a script
$ nohup ./myscript </dev/null >/dev/null 2>&1 &
and then kill it
$ pkill myscript
How can my script be designed so that when it receives the SIGKILL signal, another command is run?
You can't catch SIGKILL (and SIGSTOP), so enabling your custom handler for SIGKILL is moot.
You can catch all other signals, so perhaps try to make a design around those.
Also while doing:
pkill myscript
be default pkill will send SIGTERM, not SIGKILL, which obviously can be caught.
For example, inside your script, at top, add:
trap 'echo foobar' TERM
The trap shell builtin is used to trap a signal, and dispatch any custom handler, or ignore the signal altogether.
Here the command echo foobar will be run, when the shell receives TERM.
You can do the same for other signals too, also modify the command to meet your need. For example, running both echo foobar and executing a custom handler script:
trap 'echo foobar; /my/custom/handler.sh' TERM
If you have plan to exit after that:
trap 'echo foobar; /my/custom/handler.sh; exit' TERM
Has accepted answer says, you cannot catch SIGKILL. By the way, you can still watch for the PID of your script to see if it is still running. This can even be done by launching this watcher in a subprocess of your current script :
#!/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"
Original trap script from https://stackoverflow.com/a/39128574/1324228