Raspberry Pi: Launch Python Script on Startup

614,367

211

87

Posted in TechnologyRaspberry-pi

Introduction: Raspberry Pi: Launch Python Script on Startup

About: Scott Kildall is an new media artist and researcher. He works at Autodesk, Pier 9 and is an artist-in-residence with the SETI Institute

As I've been working on my own Pi projects, I've been discovering many little tricks and tips by scouring various websites and assembling information, testing and optimizing.

So, here is another one of my "meat-and-potatoes" Raspberry Pi Instructables.

This Instructable will show you how to setup your Raspberry Pi to automatically launch a Python script upon startup.

First of all, I know this is a lame picture. If you can come up with a better one, I'm open to suggestions.

The Arduino has auto-launch built into it; the Pi does not. This will make your Pi a more powerful electronics platform and is essential if, for example, you want to use your Pi as a video kiosk using GPIO controls.

Before doing this Instructable, please make sure you have your Raspberry Pi up and running, which you can do with The Ultimate Raspberry Pi Configuration Guide Instructable.

I'm using the Mac OS for this guide, but you can extend the principles to other operating systems.

Step 1: Make a Launcher Sript

I'm building out a new project called Black Box Timelapse (Instructable coming soon...).

My python script is called : bbt.py and lives in a directory called bbt that is in the root directory. You can substitute your own director/Python script name instead of using mine.

We will use the Linux crontab to run the Python script.

I've had trouble with crontab and directory management and my solution is to amke a shell script, which always navigates to the proper directory and will launch my bbt.py Python script. 

Let's create the shell script!

I'm using ssh to access to Raspberry Pi. My IP address for the SD card for this is 10.0.1.68. Your IP address may be different — just change the address accordingly.

Open the Terminal window and on the command line, type:
ssh pi@10.0.1.68

If you are running directly hooked into the monitor, you can skip this step.

Type in:
cd bbt
then:
nano launcher.sh
Will launch your editor, type in this script

#!/bin/sh
# launcher.sh
# navigate to home directory, then to this directory, then execute python script, then back home

cd /
cd home/pi/bbt
sudo python bbt.py
cd /

Cntl-X, Return to save.

What this script will do is to navigate to the root directory, then to the bbt directory, launch the Python script and then return to the root directory.

Step 2: Make It Executable

We need to make the launcher script an executable, which we do with this command
chmod 755 launcher.sh
Now test it, by typing in:
sh launcher.sh
This should run your Python code.

Step 3: Add Logs Directory

We will get to using crontab in a minute, but first we need to make a directory for the any errors in crontab to go.

Navigate back to your home directory:
cd
Create a logs directory:
mkdir logs

Step 4: Add to Your Crontab

crontab is a background (daemon) process that lets you execute scripts at specific times. It's essential to Python and Raspberry Pi. The details are confusing, as is often the case with Linux. Once I got the hang of the format, I've found it to be incredibly easy to use.

Here's the Linux reference and here are some more crontab examples.

Type in:
sudo crontab -e
This will brings up a crontab window.

Now, enter the line:
@reboot sh /home/pi/bbt/launcher.sh >/home/pi/logs/cronlog 2>&1
What this does is rather than executing the launcher script at a specific time, it will execute it once upon startup.

Step 5: Reboot and See If It Works

Unplug the power or just type in:
sudo reboot
Wait for startup and see if your script automatically launches.

If it doesn't work, check out the log file:
cd logs
cat cronlog
This will show you any errors that you might have.

Step 6: Always Make an Exit Plan!

You'll want to have an easy way to exit the code, so that you don't get stuck in an endless buggy loop.

The way I do this is to plug in the keyboard (not plugged in for standard kiosk usage) and exit the script this way.

In a standard Python script, you can always hit cntl-C, which will exit.

If using the pygame libraries, you can do an exit on keydown, such as:
while not done:
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            done = True

Step 7: Extra: Crontab for Timed Scripts

Another way you can use crontab is to execute scripts at specific times, such as every minute, every hour, at a specific time. This is especially helpful for projects such as Twitterbots, which I'm using for my Bot Collective project

In this case, you want to make sure your Python script exits and isn't stuck in a loop, otherwise you may end up launching the script multiple times.

Here are some examples, with the same bbt.py/launcher code:

# every 2 minutes
*/2 * * * * /home/pi/justdiedbot/launcher.sh >/home/pi/logs/cronlog.log 2>&1

# at 6:22 EST, 3:22 PST (we are on PST); 15:22
22 15 * * * /home/pi/marktwainbot/launcher.sh >/home/pi/logs/cronlog.log 2>&1


Step 8: Done!

I hope this was helpful!
Scott Kildall

For more on Raspberry Pi code and other projects, you can find me here:
@kildall or www.kildall.com/blog

7 People Made This Project!

Recommendations

  • Woodworking Contest

    Woodworking Contest
  • Make it Move Contest

    Make it Move Contest
  • Microcontroller Contest

    Microcontroller Contest
user

We have a be nice policy.
Please be positive and constructive.

Tips

2 Questions

0

Hello, great tutoriel but i have a question im using the Desktop version (for needs to visualize my code) but now that it's running background how can i send Ctrl+C to it? how can i view it's terminal?

Hi it don't work and there is no log either

87 Comments

This method works only for reboot (rebooting with command) not for Startup or power on.

I am looking for method which can execute script on Power On (startup)

i think its beter to check whether the process is running and if it fails relaunch

  1. Add this line to the file that just opened
    */5 * * * * pgrep -f myscript.py || nohup python /home/you/scripts/myscript.py > test.out

I am having an error running my script on boot.

ImportError: no module named imutils

I have tested my script an it runs without errors, I also checked that it imports everything that is needed. But when I run it on boot (following the steps above) it seems it can't import modules. Is there anything else that I needed to do?

1 reply

hi, I also have this problem. if you solve it may you share it with me?

thanks

Hi Scott, this is a really cool way and works. except that I have one problem. the script runs only when I reboot. It doesnot work when I start my rasppi. any idea why?

Scott, really cool thank you. You helped me out when using the rc.local file wasn't running on boot.

One piece of feedback, is that crontab should be able to just run the python script directly, without needing to create a bash wrapper script to launch python.

You can add the line:
@reboot python /absolute/path/of/my/script.py

To cron and it will run fine. The logger line you added above also is helpful too.

If your script uses python 3, then just use something like:

@reboot python3 /absolute/path/of/my/script.py

Running it this way will avoid the need to use cd commands in bash to connect to the directory. Just assume you're starting from root at boot, and then call the script with its direct path.

Great Instructable. Helped a ton.

HELP! I did this and now I have a black screen on boot! What do I do?

1 reply

What python script is executed?

Traceback (most recent call last):

File "assistant_library_with_button_demo.py", line 31, in <module>

import aiy.assistant.auth_helpers

File "/home/pi/AIY-voice-kit-python/src/aiy/assistant/auth_helpers.py", line 24, in <module>

import google_auth_oauthlib.flow

ImportError: No module named google_auth_oauthlib.flow

Hi,

First of all, great tutorial. Very clear.

However I am having an error in my MySQL connection.

_mysql_exceptions.OperationalError: (2002, 'Can\'t connect to local MySQL server through socket \'/var/run/mysqld/mysqld.sock\' (2 "No such file or directory")')

I think that maybe have to be the user who run the script but I to noob in linux to know.

Thanks in advance.

Hi, total noob here !
Before getting to this tutorial, i ran the .py manually in the terminal.

I managed to get launcher.sh to launch my python script, but when my raspy reboots nothing happens( i dont see a terminal where i can read my data inputs like my working .py would). Also, when i try to reach the logs , an error says they dont exist, eventhough the log directory already exists.

Thanks for the guide. It's working just fine. I am running a bot for discord. However it boots and works just fine and everything but there is no terminal popping while it's on. The bot uses feedback on the terminal.

I am trying to do similar experiment but I am stuck at one place, my python script has one statement in which I am untarring a big tar file (2.8G after untar). I have kept this python script in my crontab -e, so when I reboot and login to the machine, I see that tar command is still going on. I was assuming that when we give any script to crontab -e, it will complete full execution of the script and then only show linux logged in prompt. Can you please help me with this?

Good evening, I'm following the tutorial, but when I test launcher.sh I have the following error:

Traceback (most recent call last):
File "test.py", line 3, in
Import pygame
ImportError: No module named pygame


I'm using "import pygame" in my python script, do I need to do anything else for launcher.sh to recognize pygame?

1 reply

Hey,

Is your python code working when you use it directly, I mean on shell?

Try it first "sudo python test.py "

If you get the same error then there is a problem with your script. look out if there is any because module import can be done on this launcher.sh script.

Let me know if it works or if you have any doubt.

Cheers!

What does the "755" after chmod do. I know the 7 stands for: read, write, execute and the 5 for: read, execute. But why do you need three of those numbers and not 1?

2 replies

When using the numeric method of assigning permissions in Unix/Linux, the values are in octal. So, you have three "masks" for each file's permissions. Owner, group, & everyone else. Like so:


OwnGrpOth

421421421

rwxrwxrwx

You add up the values for each permission granted for owner, group, & other. Typically for a script you'd want the owner to have read, write, & execute access, while granting only read & execute access to the group & other users.

Owner (4+2+1) = 7

Group & Other (4+1) = 5 (twice)

chmod 755 filename

HTH.

The 7 is the permissions for the Owner, First 5 is the permissions for the Group assigned and second 5 is the permissions for the every other user on the system.

One number will be the equivalent of 777 so anyone can read, write,execute.

For more info, open the terminal and enter "man chmod" it will show you the manual page for how to use chmod

I am tryin to run a camera Python program with a GUI and i get an error:

"no display name and no $DISPLAY environment variable"

Can you help me?

Jello dare

Not to be un-nice or un-positive or un-constructive, but to try to gently correct some minor technical errors I submit for your consideration the following:

In your descriptive text you claim that your bbt is in the root, but the script clearly indicates otherwise: it's under /home/pi/ instead - which does make more sense than if you HAD put it in /

By the same token, it's redundant to talk about "navigate to home directory, then this directory..." when the script is navigating first to the root, not home, then to the afore-mentioned bbt directory. It's pointless to change to root at the top of the script and questionable to do so at the end?? It's a simple one-line command to get to bbt in the first place, regardless of where you're starting, with this:

cd /home/pi/bbt

and it might make more sense to execute this instead at the end:

cd ~

which will put you back to your default "home" directory whence you LIKELY came in the first place.

Thanks for helping so many folks with this, though!

pw