How to Run a Raspberry Pi Program on Startup

Pages
Contributors: Shawn Hymel
Favorited Favorite 22

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 &
Note: the ampersand (&) at the end of the line is needed so that your Python script runs in a different process and does not block execution of the boot process. Without it, the rc.local script would wait for your script to end before continuing, and if you have an infinite loop (like in our blink.py program), you would never get a login prompt.

Modifying rc.local to run a Python script on boot

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>
Heads up! Make sure you type the PID correctly! If you kill the wrong process, you could halt Linux, and you would need to reboot again.

Terminating a process with the kill command

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.