Python script as daemon in ubuntu - python

I created a daemon to run a python script. but it stops whenever i logout from my ubuntu machine.
DAEMON=sudo python /var/www/some_dir/my_python.py
ARGS=/var/www/some_dir/my_python.py
PIDFILE=/var/www/some_dir/my_python.pid
test -x $DAEMON || exit 0
#set -e
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON &
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --pidfile $PIFDILE --exec $DAEMON
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --pidfile $PIDFILE --exec $DAEMON
sleep 1
start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON &
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
can anyone tell me how can i do it.

It's a long time since this question was asked, but I came across this situation today.
To start the process in the background, use
start-stop-daemon -Sbm --pidfile $PIDFILE --exec $DAEMON
To stop it:
start-stop-daemon -K --pidfile $PIDFILE
From the start-stop-daemon man page:
-b , -background
Force the daemon into the background. Some daemons don't create
pidfiles, so a good trick is to get the daemon to run in the
foreground, and use the this option along with -m , -make-pidfile to
create a working pidfile.
-m , -make-pidfile
Saves the pid of the daemon in the file specified by the -p, -pidfile
option. Only useful when used with daemons that run in the foreground
and forced into the background with the --b, -background option.

Try to remove & from your start-stop-daemon invocations. Also, you should read how to write proer initscripts because there are several other errors in your initscript.

Related

daemonizing a python script: What is better? start-stop-daemon or python-daemon

I like to start a python program as a daemon. I checked a bit the internet and came up with two solutions.
The first one is to use start-stop-daemon on something like this
#!/bin/sh
start() {
start-stop-daemon -S -q -m -b -p /var/run/sample.pid --exec /usr/bin/python /bin/sample.py && echo "OK" || echo "Failed"
}
stop() {
start-stop-daemon -K -q -p /var/run/sample.pid
}
case "${1}" in
start)
start
echo "sample service started"
;;
stop)
stop
echo "sample service stopped"
;;
restart)
stop
start
echo "sample service restarted"
;;
*)
echo "usage: $0 {start|stop|restart}"
;;
esac
The second one is to use python-daemon
so I guess we have an extra python file - lets name it "sampleDaemon.py"
import daemon
import sample
with daemon.DaemonContext():
sample()
And a bash script (I am not sure about that - I guess this way):
#!/bin/sh
/usr/bin/python /bin/sampleDeamon.py
What is the best way to do it? What are the limitations? The python-deamon documentation is not that big(or I didn't found it).

PyQt: How to run GUI on Raspberry Pi desktop startup?

Dear Stackoverflow community,
I am struggling with running a python script that executes a PyQt5 GUI on desktop startup of Raspberry Pi 3B with Raspbian Jessie.
What do I have so far?
Python script with shebang #!/usr/bin/env python3 in first line (python3 --version is 3.4.2) running the GUI without any problems
Shell script (.sh) that is able to execute the GUI with the following lines:
#!/bin/bash
python3 GUI.py
Information that may help:
If I place both files in the same directory somewhere, the Shell script starts the GUI, but if they are on the desktop, it doesn't.
Automatic login to desktop is enabled.
Thank you in advance for any help.
RaspiManu
UPDATE:
I solved my Problem with a lot of testing and posted an answer for other users.
After a lot of testing, I figured it out myself. Here's how it worked for me...
Create autorun-file:
2.1 LXTerminal: cd /home/pi/.config/autostart
2.2 LXTerminal: sudo nano pythonscript.desktop
2.3 pythonscript.desktop:
[Desktop Entry]
Version=1.0
Name=YourName
Comment=Your comment
Exec=/home/pi/pythonscript.py -nograb #-nograb for comboBox on touch Screen
Icon=/usr/share/pixmaps/python.xpm
Path=/home/pi/
Terminal=false
StartupNotify=true
Type=Application
Categories=Utility;Application;
2.4 Ctrl+O, Ctrl+X, sudo reboot
Good to know:
It is important, that you can't use just any path to your script. The script has to be directly in the /home/pi/ directory, so you would use Exec=/home/pi/pythonscript.py in the autorun-file (.desktop). I also learned, that if your script loads for example an image with PIL, this image has to be somewhere else, maybe on your desktop, because it can't be opened out of the /home/pi/ directory.
If your GUI has a comboBox and you are using a touch screen, the comboBox might make your whole GUI unuseable after you touched it. Using Exec=/home/pi/pythonscript.py -nograb solves this problem.
StartupNotify=true is important for starting GUI scripts.
Hope this helps,
RaspiManu
You can make a background service that runs on startup, by following this link
Service method
and By appending this line
service yourdaemon start
in /etc/rc.local
assuming your service name is 'yourdaemon'
Caution: Use the root previleges
Example service file
#! /bin/sh
### BEGIN INIT INFO
# Provides: yourdaemon
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Your Daemon
# Description: Your Daemon
### END INIT INFO
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Your Daemon"
NAME=yourdaemon
DAEMON=/hannext/yourdaemon.py # Path to your python file
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
LOGFILE=/var/log/snc/$NAME.log
. /lib/lsb/init-functions
do_start()
{
echo "$(date +%F) $(date +%T) DAEMON : Starting $DESC service" >> $LOGFILE
start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON --make-pidfile --background
}
do_stop()
{
echo "$(date +%F) $(date +%T) DAEMON : Stopping $DESC service" >> $LOGFILE
start-stop-daemon --stop $DAEMON --quiet --oknodo --pidfile $PIDFILE
rm -f $PIDFILE
}
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
#log_daemon_msg "Reloading $DESC" "$NAME"
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:
save it by the name of 'yourdaemon' in /etc/init.d/ and make it executable using
chmod +x yourdaemon

Linux start-stop-daemon directory error calling shell/python script

I am just getting acquainted with Linux and I cannot seem to get the start-stop-daemon to run a python script due to directory issues. In a linux file structure I have the files:
~/test.txt
THIS LINE IS A TEST
~/test.py
#!/usr/bin/python
import time
with open("test.txt") as f:
while True:
try:
print("Hello World")
print(f.readline())
time.sleep(2)
except KeyboardInterrupt:
f.close()
break
~/test.sh
#!/bin/bash
echo "SHELL SCRIPT SUCCESS" > /var/log/test.log
cd ~/
./test.py > /var/log/test.log
Upon calling sudo bash ~/test.sh from any directory the test.log is populated as expected with the stdout originating from test.py. For some reason, starting the following start-stop-daemon service script WILL generate a test.log but does NOT populate it with the stdout:
/etc/init.d/test
#!/bin/sh
### BEGIN INIT INFO
# Provides: Python test script
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Prints out daemonized argument
# Description: Creates output of argument
### END INIT INFO
DAEMON_DIR=/home/alex
DAEMON=$DAEMON_DIR/test.sh
DAEMON_NAME=test
DAEMON_OPTS="hello"
DAEMON_USER=root
PYTHON=/usr/bin/python
PIDFILE=/var/run/$DAEMON_NAME.pid
. /lib/lsb/init-functions
do_start () {
log_daemon_msg "Starting system $DAEMON_NAME daemon"
#start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --exec $PYTHON --startas $DAEMON
start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --chuid $DAEMON_USER --startas /bin/bash /home/alex/test.sh
log_end_msg $?
}
do_stop () {
log_daemon_msg "Stopping system $DAEMON_NAME daemon"
start-stop-daemon --stop --pidfile $PIDFILE --retry 10
log_end_msg $?
}
case "$1" in
start|stop)
do_${1}
;;
restart|reload|force-reload)
do_stop
do_start
;;
status)
status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
;;
*)
echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
exit 1
;;
esac
exit 0
Is this a directory issue that can be addressed within the start-stop-daemon?
Alternatively I'd be open to other methods of script servicing that can persist through a cold boot (i.e. no cron jobs)
Try calling cd using an absolute path, for example /home/alexjg/ instead of ~/; the reason it was broken before is that in your example you're using sudo which keeps the home directory of the user running it. However when you're calling the bash script from init it will use root's home directory instead which doesn't contain test.py.
The file is created because the redirection is still succeeding; however because starting Python failed there was no output.

Python script on boot Linux

I would like to launch my python program (Graphical User Interface) on startup in Linux (Raspbian on a Raspberry PI).
I've made an initscript to launch my Python program, and I put it in the etc/init.d map.
I enabled it with the update-rc.d command. It all works fine.
But my Python script won't start with the following code in the initscript:
#!/bin/bash
### BEGIN INIT INFO
# Provides: GUI
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: This is a test daemon
# Description: This is a test daemon
# This provides example about how to
# write a Init script.
### END INIT INFO
case $1 in
start)
python3 /home/pi/Desktop/GUI/GUI.py
;;
stop)
# Stop the daemon.
if [ -e $PIDFILE ]; then
status_of_proc -p $PIDFILE $DAEMON "Stoppping the $NAME process" && status="0" || status="$?"
if [ "$status" = 0 ]; then
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
/bin/rm -rf $PIDFILE
fi
else
log_daemon_msg "$NAME process is not running"
log_end_msg 0
fi
;;
restart)
# Restart the daemon.
$0 stop && sleep 2 && $0 start
;;
status)
# Check the status of the process.
if [ -e $PIDFILE ]; then
status_of_proc -p $PIDFILE $DAEMON "$NAME process" && exit 0 || exit $?
else
log_daemon_msg "$NAME Process is not running"
log_end_msg 0
fi
;;
reload)
# Reload the process. Basically sending some signal to a daemon to reload
# it configurations.
if [ -e $PIDFILE ]; then
start-stop-daemon --stop --signal USR1 --quiet --pidfile $PIDFILE --name $NAME
log_success_msg "$NAME process reloaded successfully"
else
log_failure_msg "$PIDFILE does not exists"
fi
;;
*)
# For invalid arguments, print the usage message.
echo "Usage: $0 {start|stop|restart|reload|status}"
exit 2
;;
esac
The problem is that when the init script run, there is not graphical interface available. Instead of using a init script, try configuring your application to run on X startup.
First add the command line to start your GUI app to ~/.xinitrc
# ~/.xinitrc
exec python3 /home/pi/Desktop/GUI/GUI.py
And then start the X server
startx

custom linux daemon won't stop using "service stop"

I've written a custom python daemon that runs as a service via an init.d script on ubuntu 14.04. Starting the service works fine, but when I try to do "service monitor stop", the daemon is not terminated. I'm using pyinotify to daemonize a file watcher for changes.
Within the init.d script:
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Monitor files"
NAME=monitor
DAEMON=/usr/bin/python
DAEMON_ARGS="/home/user/python/monitor.py"
PIDFILE=/home/user/logs/monitor.pid
LOGFILE=/home/user/logs/monitor.log
SCRIPTNAME=/etc/init.d/$NAME
...
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
echo "done"
}
...
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
...
To ensure the daemon handles SIGERM properly, I can run it by hand:
bash$ /usr/bin/python /home/user/python/monitor.py
bash$ kill -Term PID
The daemon successfully handles the SIGTERM and exits properly.
I can't seem to figure out why it doesn't handle it when I do "service monitor stop" though.
Check that the process $NAME is correct, as delivered to the start-stop-daemon --stop command. I just encountered this issue because a process I was running ended up getting a different name whenever it forked its daemon. Try running this to see the process command name:
ps -o comm= $(cat /home/user/logs/monitor.pid)
I bet yours outputs this (instead of monitor):
python
Then change your stop command to look like this, where you substitute python in place of $NAME:
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name python

Categories