#!/bin/sh term_handler () { if [ "$ok_to_exit" -eq 1 ]; then echo 'exiting' exit else echo 'refusing to exit' fi } trap term_handler TERM ok_to_exit=0 pkill -f test.sh ok_to_exit=1 while true; do echo 'working...' sleep 2 done This script (of which there is a simpler version below) installs a signal handler, the term_handler function, which will exit the script upon receiving a TERM signal if the ok_to_exit variable's value is 1.
In the body of the script is a loop simulating some form of work being carried out. The important bit is that before calling pkill (you may change this to your killall command), it sets ok_to_exit to 0, and directly afterwards it sets it to 1.
When sending out the TERM signal to all matching processes, it will receive the signal itself, but it will refuse to exit. Any other matching processes, if it's not also in the exact same state (which could happen if you started the script more than once simultaneously), would terminate.
When running, this script would output
refusing to exit working... working... working... When another copy of the script is started, it outputs exiting and then terminates.
A simpler version of the same script:
#!/bin/sh trap '' TERM pkill -f test.sh trap - TERM while true; do echo 'working...' sleep 2 done This simply ignores the TERM signal during the call to pkill, and then reinstates the default signal handler before continuing.