2

I am developing a monitoring program using bash. This program will be running continuously, and if I update the bash code, this should rerun the new code without exiting(Basically hot upgrade).

I tried to do this by using SIGUSR2 and exec-ing the same script again.

It is working correctly the first time, the SIGUSR2 signal is caught and the new script is exec-ed. But after the first exec, it's not responding to SIGUSR2 anymore.

#!/bin/bash

VERSION=v1
upgrade()
{
    export GOT_UPGRADED=true
    echo "Upgrading..."
    exec $HOME/workspace/test/upgrade_test
}

init()
{
    if [[ $GOT_UPGRADED != true ]]; then
        # won't initialize again, if it's got upgraded.
        echo "Initializing..."
    fi
}

monitor()
{
    echo "$VERSION: Monitoring..."
}

trap upgrade SIGUSR2 # if SIGUSR2 is received, upgrade.

init
while true; do
    monitor
    sleep 1
done;

Sample Run:

shell1: ./upgrade_test
Initializing...
v1: Monitoring...
v1: Monitoring...
v1: Monitoring...
v1: Monitoring...
v1: Monitoring...
Upgrading...                  # Sent from shell2
v1: Monitoring...
v1: Monitoring...
v1: Monitoring...
v1: Monitoring...

Meanwhile in shell2:
pkill -SIGUSR2 -f upgrade_test; # here it got upgraded
pkill -SIGUSR2 -f upgrade_test; # THE PROBLEM: doesn't work anymore

How can I keep the SIGUSR2 hanlder working even after exec?

Thanks,

7
  • 1
    exec replaces the shell, what remains to execute the trap? Why use exec?
    – muru
    Mar 11, 2021 at 7:31
  • exec command is running the same program again, so can't that shell trap SIGUSR2? I am trying to find a way to update the program without closing it, hence using exec, please let me know if some other way is there.
    – Insaf K
    Mar 11, 2021 at 7:36
  • Actually running this as bash ./upgrade_test instead of just ./upgrade_test solved the problem. What happened here?
    – Insaf K
    Mar 11, 2021 at 7:38
  • Is bash the same as /bin/bash? What does command -v bash report?
    – muru
    Mar 11, 2021 at 7:39
  • You are right! /bin/bash and bash are running different bash. /bin/bash is v3.2.57, /usr/local/bin/bash is v5.0.18, which is ran by bash command. So this could be an issue that is fixed in newer bash?
    – Insaf K
    Mar 11, 2021 at 8:05

1 Answer 1

0

Works fine for bash version 4.4

#!/bin/bash

########################################################################
#
trapped()
{
    echo "Oh oh I'm trapped"
    exec "$0" "$@"

    echo "exec failed: $0 $*"
    exit 1
}

########################################################################
# Go
#
trap trapped SIGUSR2

echo "Running new instance as PID $$"
while :
do
    read -p "$(date): " -t 120 X; ss=$?; echo
    [[ $ss -eq 1 ]] && exit
done

Running this as /tmp/trap.sh,

Running new instance as PID 3899
11 Mar 2021 10:29:22: Oh oh I'm trapped
Running new instance as PID 3899
11 Mar 2021 10:29:36: Oh oh I'm trapped
Running new instance as PID 3899
11 Mar 2021 10:29:38:

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .