Launch Python script at boot
Sometimes we could need to start a Python script when Raspberry Pi boots up in a full autonomous way.
RPi could be really useful if used headless, without a direct user interaction (at least when starting the system), so if we created a script for a RPi that needs to be executed at startup, we also need a way to accomplish this task.
In this post I will describe a way to execute a Python script (but this works also for every other kind of software) when booting the RPi.
The best way is to run the script at boot is to launch it as a daemon.
To keep it simple, a daemon is a task executed in background, so the system can run it in parallel with other tasks.
Lets see a small example script:
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import time
i=0
while True:
i=i+1
if (i>10): i=0
time.sleep(10)
This script just increments a variable every ten seconds. Not quite a useful task indeed, but can shows some things that we need.
First of all the beginning row is mandatory. It specify how to execute the script (actually calling it with the Python interpreter).
The second line could be omitted, but some script may have problems without it, so its better to keep it in the source.
Everything else is just a simple Python script, but note that we have an infinite loop (the while True statement). Without this loop the script will run just one time.
Now save this script. For this post Im saving as testing.py in the /home/pi folder.
If you wish, you can check if it works with the command
You can of course stop it with CTRL-C.
As we specified in the first line of the script that this is a Python script, we can run it without invoking the interpreter. Lets make it executable with the following command:
and lets try to launch the script directly:
The ./ before the script name is needed by Linux if you are executing something in the current folder. Now create a new text file named testing.sh (its better to keep the same name of the python script, just for clarity) and fill it with the following code:
This will run our script as a daemon. You can change some variable to adapt to other scripts (just look at the comments). Note that for some script you should change the daemon user from pi to root to make it work.
Next we need to copy this script to the init.d folder and make it executable:
You can start/stop/check/restart the daemon using the following commands:
but of course we want to make it start automatically, so just type one last command:
and reboot the Raspberry Pi. You can check if your script is working by using the status command above.
Thats all, but of course remember that if an error occours in your script, you need to restart the daemon manually.
Also note that when you run something as a daemon, no output text will be generated, so you may need some logging to eventually keep track of information from your script.
Everything else is just a simple Python script, but note that we have an infinite loop (the while True statement). Without this loop the script will run just one time.
Now save this script. For this post Im saving as testing.py in the /home/pi folder.
If you wish, you can check if it works with the command
python testing.py
You can of course stop it with CTRL-C.
As we specified in the first line of the script that this is a Python script, we can run it without invoking the interpreter. Lets make it executable with the following command:
sudo chmod 755 testing.py
and lets try to launch the script directly:
./testing.py
The ./ before the script name is needed by Linux if you are executing something in the current folder. Now create a new text file named testing.sh (its better to keep the same name of the python script, just for clarity) and fill it with the following code:
#!/bin/sh
### BEGIN INIT INFO
# Provides: testing
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: testing boot execution
# Description: example for launchinga python script at boot time as a daemon
### END INIT INFO
# Change the next 3 lines to specify where you install your script and what you want to call it
DIR=/home/pi
DAEMON=$DIR/testing.py
DAEMON_NAME=testing
# Add any command line options for the daemon here
DAEMON_OPTS=""
# This next line specify what user the script runs as.
DAEMON_USER=pi
# The process ID of the script when it runs is stored here:
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 --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
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
### BEGIN INIT INFO
# Provides: testing
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: testing boot execution
# Description: example for launchinga python script at boot time as a daemon
### END INIT INFO
# Change the next 3 lines to specify where you install your script and what you want to call it
DIR=/home/pi
DAEMON=$DIR/testing.py
DAEMON_NAME=testing
# Add any command line options for the daemon here
DAEMON_OPTS=""
# This next line specify what user the script runs as.
DAEMON_USER=pi
# The process ID of the script when it runs is stored here:
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 --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
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
This will run our script as a daemon. You can change some variable to adapt to other scripts (just look at the comments). Note that for some script you should change the daemon user from pi to root to make it work.
Next we need to copy this script to the init.d folder and make it executable:
sudo mv ./testing.sh /etc/init.d
sudo chmod 755 /etc/init.d/testing.sh
sudo chmod 755 /etc/init.d/testing.sh
You can start/stop/check/restart the daemon using the following commands:
sudo /etc/init.d/testing.sh start
sudo /etc/init.d/testing.sh stop
sudo /etc/init.d/testing.sh status
sudo /etc/init.d/testing.sh restart
sudo /etc/init.d/testing.sh stop
sudo /etc/init.d/testing.sh status
sudo /etc/init.d/testing.sh restart
but of course we want to make it start automatically, so just type one last command:
sudo update-rc.d testing.sh defaults
and reboot the Raspberry Pi. You can check if your script is working by using the status command above.
Thats all, but of course remember that if an error occours in your script, you need to restart the daemon manually.
Also note that when you run something as a daemon, no output text will be generated, so you may need some logging to eventually keep track of information from your script.