Shell Script -kill all process by name but me

killshell-script

I have shell script test.sh that I running.

I want that in the beginning of this script ,if there are older test.sh that running ,kill them first.

If I killall test.sh the newest process killed too.

I there any simple way to do it ?

Best Answer

#!/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.

Related Question