How to Run a Raspberry Pi Program on Startup
Method 1: rc.local
Running your program from rc.local is likely the easiest method, but because rc.local is executed before X starts, you will not have access to GUI elements. As a result, it's recommended that you only use rc.local for starting programs that do not have graphical elements.
As your Linux operating system (OS) boots on your Raspberry Pi, it goes through a series of runlevels, which define the state of the system during startup. Whenever the runlevel changes, various run control (rc) scripts are run, which handle starting and stopping various system services. If you would like to learn more about rc scripts, see this article, but for our purposes, we just need to worry about rc.local.
The rc.local script is executed after all of the normal system services have been started (including networking, if enabled) and just before the system switches to a multiuser runlevel (where you would traditionally get a login prompt). While most Linux distributions do not need an rc.local, it's usually the easiest way to get a program to run on boot with Raspbian.
Modify rc.local
You will need root-level access to modify rc.local, so do so with sudo:
language:shell
sudo nano /etc/rc.local
Scroll down, and just before the exit 0
line, enter the following:
language:shell
python /home/pi/blink.py &
Notice that we are calling our script with the absolute file location (/home/pi/blink.py
), as calling python blink.py
from within rc.local will cause python to look for a local file (i.e. blink.py file located in the same directory as rc.local). We use the absolute file location to make it explicit to Python where our program can be found.
Save and exit with ctrl + x, followed by y when prompted to save, and then enter.
Test it by restarting your Pi with sudo reboot
.
Troubleshooting
Nothing Happens
If your script is not running, ensure that your script is called with the absolute directory name (e.g. python /home/pi/blink.py &
).
If you cannot access the desktop because your script is preventing Linux from finishing its boot sequence, then you might have to get a terminal over serial. Follow these instructions to get a serial terminal into the Pi.
If you cannot get a serial terminal into your Raspberry Pi, then you will likely need to plug your SD card into another computer (Linux or macOS), navigate to etc/rc.local, and remove the line that calls your Python script.
Debugging
You might notice that you don't see any errors or output from your script, as rc.local does not log or output any information. To get that, change the python call in your rc.local file to the following:
sudo bash -c 'python /home/pi/blink.py > /home/pi/blink.log 2>&1' &
This creates a new shell with sudo
(superuser privileges), runs your script, and redirects the output (stdout) to the blink.log file. 2>&1
Says that errors (stderr) should also be redirected to the same log file. Upon rebooting, any output from your Python script (e.g. print()
statements) as well as errors should be saved to blink.log. To view the log, enter the following into a terminal (note that you might need to stop your program first to view the contents of the log file):
language:shell
cat blink.log
Use a Specific Version of Python
As it turns out, rc.local runs before .bashrc, so the command python
still refers to Python 2 in our startup script! To explicitly call Python 3, we should change our rc.local command to:
language:shell
sudo bash -c '/usr/bin/python3 /home/pi/blink.py > /home/pi/blink.log 2>&1' &
How to Stop Your Program
You might notice that your program runs great, but there's no easy way to stop it! The simplest method would be to remove (or comment out) the line you added in rc.local followed by a reboot, but that takes a lot of time.
The quickest way to stop your program is to kill its Linux process. In a terminal, enter the following command:
language:shell
sudo ps -ax | grep python
ps -ax
tells Linux to list out all the currently processes. We pipe that list to grep
, which allows us to search for keywords. We're looking for python in this example, but feel free to change it to the name of your program or whatever you are using to run your program. Find the process ID (PID) number to the left of the listed process, and use the kill
command to terminate that process:
language:shell
sudo kill <PID>
If you are using the blink.py example, you should see the LED cease flashing.
How to Stop Your Program from Running on Boot
If you no longer want your program to run on boot, simply open rc.local with:
language:shell
sudo nano /etc/rc.local
Delete the line that you added to run your program, and save and exit with ctrl + x and y. Reboot your computer, and your program should no longer run after boot.
Another Option
rc.local is a good place to start your program whenever the system boots up (before users can log in or interact with the system). If you would like your program to start whenever a user logs in or opens a new terminal, consider adding a similar line to /home/pi/.bashrc
.