3

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?

Thomas W.
  • 430
  • 5
  • 21
user123456
  • 2,348
  • 5
  • 31
  • 53

2 Answers2

4

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
heemayl
  • 90,425
  • 20
  • 200
  • 267
2

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

JBreton
  • 121
  • 2