I want to start some python script (with venv) at startup and monitor the status, for auto restart it if something goes wrong.
I've made:
- a simple python example prg.py that sleep forever and exit if it receive a sigint signal.
a bash script
prg.shthat monitor the execution ofprg.py. If the process stop, the script restart the program. If the script receive the sigint, it will send a sigint to theprg.pyprogram and exit.A
init.dscript (prg) for start the bash script (prg.sh). The code ofprgis not mine, I've found it on GitHub and modified it. I'm searching the link, When I will found it I will edit the post.
prg.py:
import signal
import time
def signal_handler(sig, frame):
print('sigint')
quit(0)
signal.signal(signal.SIGINT, signal_handler)
print ('aaa')
while (1):
time.sleep(1.5)
prg.sh:
#!/bin/bash
#set -x
DIR="/home/pi"
PRESCRIPT="source venv/bin/activate;python --version"
SCRIPT="python prg.py"
EXITDO=0
PID=-1
trap ctrl_c INT
function ctrl_c() {
echo 'SIGINT intercepted.'
EXITDO=1
}
#Main loop
while [ $EXITDO -eq 0 ]; do
echo 'Starting process…'
cd "$DIR"
eval $PRESCRIPT
$SCRIPT &
PID=$(echo $!)
echo "Process started with PID: $PID"
while $(kill -0 $PID) && [ $EXITDO -eq 0 ]; do
sleep 1
done
if [ $EXITDO -eq 0 ]; then
echo 'Process terminated. Restart.'
else
echo 'Kill service.'
kill -2 $PID
fi
done
prg:
#!/bin/sh
### BEGIN INIT INFO
# Provides: prg
# Required-Start: $local_fs $network $named $time $syslog
# Required-Stop: $local_fs $network $named $time $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: <DESCRIPTION>
### END INIT INFO
NAME=prg
SCRIPT="/home/pi/prg.sh"
PIDFILE=/var/run/$NAME.pid
start() {
if [ -f $PIDFILE ] && [ -s $PIDFILE ] && kill -0 $(cat $PIDFILE); then
echo 'Service already running' >&2
return 1
fi
echo 'Starting service…' >&2
#local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
#su -c "$CMD" $RUNAS > "$PIDFILE"
# Try with this command line instead of above if not workable
# su -s /bin/sh $RUNAS -c "$CMD" > "$PIDFILE"
$SCRIPT &
echo $! > "$PIDFILE"
PID=$(cat $PIDFILE)
if kill -0 $(cat $PIDFILE) > /dev/null
then
echo "$NAME is now running, the PID is $PID"
else
echo ''
echo "Error! Could not start $NAME!"
fi
}
stop() {
if [ ! -f "$PIDFILE" ] || ! kill -0 $(cat "$PIDFILE"); then
echo 'Service not running' >&2
return 1
fi
echo 'Stopping service…' >&2
#Kill by pid
kill -2 $(cat "$PIDFILE")
#remove .pid file
sleep 3
if ! kill -0 $(cat "$PIDFILE"); then
rm -f "$PIDFILE"
echo 'Service stopped' >&2
fi
}
uninstall() {
echo -n "Are you really sure you want to uninstall this service? That cannot be undone. [yes|No] "
local SURE
read SURE
if [ "$SURE" = "yes" ]; then
stop
rm -f "$PIDFILE"
echo "Notice: log file was not removed: $LOGFILE" >&2
update-rc.d -f $NAME remove
rm -fv "$0"
else
echo "Abort!"
fi
}
status() {
printf "%-50s" "Checking $NAME..."
if [ -f $PIDFILE ] && [ -s $PIDFILE ]; then
PID=$(cat $PIDFILE)
if [ -z "$(ps axf | grep ${PID} | grep -v grep)" ]; then
printf "%s\n" "The process appears to be dead but pidfile still exists"
else
echo "Running, the PID is $PID"
fi
else
printf "%s\n" "Service not running"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
uninstall)
uninstall
;;
restart)
stop
start
;;
*)
echo "Usage: $0 {start|stop|status|restart|uninstall}"
esac
If I start
prg.shthe program run as expected.I can kill
prg.pyand theprg.shauto restart theprg.py.I can send a
siginttoprg.shand theprg.shstop theprg.pyand close itself.I can start the
prgwithsudo service prg startcommand and all works fine.
BUT
in this situation the, if I send a
siginttoprg.sh, nothing happen.In simple words,
service prg stopdoes not work and I don't understand why.
Thanks in advance.