I'm trying to run a program inside an endless loop because it sometimes dies for no reason. I would like to be able to hit Ctrl-C to prevent the program being restarted though.
I don't want Ctrl-C to kill the program, just to wait until it dies, then not restart it again.
theprogram is a wine program (utorrent).
Bonus points for telling me how to make it so it will safely exit theprogram just like clicking on the 'x' in the top right of it. When I manually kill it from the command line or hit Ctrl-C, it doesn't get to run its cleanup code. Hence my attempt to just stop it being restarted.
I checked a few of the other questions about trapping SIGINT, but I couldn't work out how to do this.
Can anyone fix this code? My code seems to kill theprogram then exit the loop when Ctrl-C is pressed, without letting theprogram clean up.
#!/bin/bash
EXIT=0
trap exiting SIGINT
exiting() { echo "Ctrl-C trapped, will not restart utorrent" ; EXIT=1;}
while [ $EXIT -eq 0 ] ; do
        wine theprogram
        echo "theprogram killed or finished"
        date
        echo "exit code $?"
        echo "sleeping for 20 seconds, then restarting theprogram..."
        sleep 20
done
echo "out of loop"
Use a monitoring process:
This allows the SIGINT signal to hit the monitor process trap handler without affecting the child.
(this could also be done in perl, python or any language)
#!/bin/bash
cmd() {
    trap '' INT
    trap 'echo "Signal USR1 received (pid=$BASHPID)"; EXIT=1' USR1
    EXIT=0
    while [ $EXIT -eq 0 ]
    do
        echo "Starting (pid=$BASHPID)..."
        sleep 5 # represents "wine theprogram"
        echo "theprogram killed or finished"
        date
        echo "Exit code $?"
        if [ $EXIT -eq 0 ]; then
            echo "Sleeping for 2 seconds, then restarting theprogram..."
            sleep 2
        fi
    done
    echo "Exiting (pid=$BASHPID)"
}
run() { cmd & PID=$!; echo Started $PID; }
graceful_exit() { kill -s USR1 $PID && echo "$PID signalled to exit (USR1)"; }
shutdown() { kill -0 $PID 2>/dev/null && echo "Unexpected exit, killing $PID" && kill $PID; }
trap 'graceful_exit' INT
trap 'shutdown' EXIT
run
while :
do
    wait && break
done
echo "Exiting monitor process"
Try this:
while true
do
  xterm -e wine theprogram || break
  sleep 3
done
The trick is done by using another xterm to start the wine. That way the wine has a different controlling tty and won't be affected by the Ctrl-c press.
The drawback is that there will be an additional xterm lingering around on your desktop.  You could use the option -iconic to start it iconified.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With