33

This question has been asked quite a few times before but I didn't seem to get it working using the existing information.

My Pi runs Raspbian. I have a Python script named dnscheck.py which loops forever.

I need it to run at boot. I know I have to create a .sh file containing something like

sudo python dnscheck.py &

What I don't know is where this file should be or if it should contain anything else. I know about the init.d folder, but seeing the skeleton example I imagine there should be a simpler way to do this simple task.

Vlad Schnakovszki
  • 1,261
  • 2
  • 15
  • 17
  • for a real easy way checkout this step by step tutorial-->https://youtu.be/Tvnrx-2QaUU make as much launchers as you need and adress all of them in crontab – Hossein RM Dec 28 '17 at 14:21

10 Answers10

21

If you want to control the process with commands like start, stop, restart etc using the skeleton script and altering it for your purposes might be the best option.

If you just want the process to start, put the command into /etc/rc.local. (I don't have my RPi at hand, but I read online that there is an 'exit 0' line in there, you should put your command above this line)

myhd
  • 342
  • 1
  • 3
  • 14
ikku
  • 4,484
  • 1
  • 25
  • 28
  • 1
    It worked! I must add that setting the permissions for the script and rc.local back to 755 (read/write/execute) is a must. Not sure if both need this setting, but it worked for me. Thanks a lot for the help! – Vlad Schnakovszki Dec 27 '12 at 00:07
  • 7
    *"as you wrote it in your question"* Not quite -- you don't need sudo as `rc.local` runs root. You should also specify the complete path to the script, obviously. **You should also add `&`** at the end so that the script forks, e.g. `/path/to/foobar.py &`. – goldilocks Feb 20 '15 at 13:15
  • 1
    @goldilocks could you please explain why do I need to add `&` ? Because when I use without it, everything still working as expected. – Huy.PhamNhu Jul 29 '17 at 03:21
  • 2
    @Huy.PhamNhu Answering your question : The Pi will run this program at bootup, and before other services are started. If you don’t include the ampersand and if your program runs continuously, the Pi will not complete its boot process. The ampersand allows the command to run in a separate process and continue booting with the main process running. – Amine Harbaoui Jul 27 '18 at 14:49
14

2020 Update:
Nowadays modern Linux distributions, including Raspbian, use systemd instead of old style SysV as init system. For downstream compatibility SysV is only emulated by systemd but will lose support more and more by time so

you should not use SysV anymore, in particular /etc/rc.local!

For more information about this have a look at Compatibility with SysV.

With the endless loop in the script it should run in the background as service so you can use a systemd service defined with a Unit file. Here is a simple example for your script. Create it with:

rpi ~$ sudo systemctl --force --full edit dnscheck.service

In the empty editor insert these statements, save them and quit the editor:

[Unit]
Description=Check DNS queries
After=multi-user.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/dnscheck.py

[Install]
WantedBy=multi-user.target

It may be possible that this is too simple and you have to add some more settings for a needed environment. Have a look at man systemd.unit and man systemd.service for additional conditions.

Enable and monitor the service with:

rpi ~$ sudo systemctl enable --now dnscheck.service
rpi ~$ systemctl status dnscheck.service

The text output of the script you will find in the journal:

rpi ~$ journalctl -b -e
Ingo
  • 41,647
  • 17
  • 82
  • 193
  • This "Answer" is 8 years too late! Why resurrect the dead? – Milliways Mar 24 '20 at 10:04
  • 4
    @Milliways You do not understand the first line: **2020 Update:**? 2020 means this year 2020. – Ingo Mar 24 '20 at 10:08
  • You regularly advise others to accept answers to stop useless questions resurfacing - but this is all your "Answer" will achieve is to resurrect the dead. This one would have remained safely in the grave otherwise. – Milliways Mar 24 '20 at 10:13
  • 4
    You are wrong with remaining this question in the grave. It is [referenced on other questions as duplicate answer](https://raspberrypi.stackexchange.com/q/108694/79866). So I think it is very important to have it up to date so that the OP doesn't follow the other old deprecated stuff. That was the reason why I updated it. – Ingo Mar 24 '20 at 10:22
  • @Milliways Forgot to reference you. Please note my comment above. – Ingo Mar 25 '20 at 10:00
7

Move your script (we will save it to the file dnscheck) to /etc/init.d/, and set the permissions so it can be run:

chmod 755 /etc/init.d/dnscheck

Add LSB init tags to the top of your script. You will probably want to change Required-Start/Stop and the Description Tags to fit your script.

### BEGIN INIT INFO
# Provides:          dnscheck
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO

Then create the symbolic links by running

update-rc.d /etc/init.d/dnscheck defaults
Izzy
  • 581
  • 6
  • 16
Bert
  • 852
  • 7
  • 10
  • 2
    Please not that while this was a decent answer 3 1/2 years ago, and will still work because Raspbian's new init system is backward compatible with LSB/SysV style scripts, new users would be better off learning to use the new system instead (*systemd*) if just adding a line to `/etc/rc.local` is insufficient. – goldilocks Jul 03 '16 at 17:32
4

There are many ways to do this, of course, but don't forget using cron. If you put a @reboot line in your crontab, that command will be executed on every restart.

To test, I just added the following line to my user crontab with crontab -e: @reboot echo "$(date)" >> ~/boot.txt The bonus to this method is that you can call the job as required at other intervals besides just boot time, and you don't have to edit init scripts.

bobstro
  • 3,978
  • 13
  • 27
3

Here is the solution that I constantly use.

Create a desktop file

xyz.desktop

type the following into it

[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=<Application Name Goes here>
Comment=
Exec=  python /home/pi/Desktop/execute_on_boot.py
StartupNotify=false
Terminal=true
Hidden=false

paste this file into the

/home/pi/.config/autostart/

and restart your raspberry pi and it should automatically run your program in a new terminal

evolutionizer
  • 296
  • 2
  • 6
  • please don't cut and paste answers to multiple questions. If the answer is the same the newer version should be flagged as a duplicate. – Steve Robillard Aug 25 '15 at 19:29
  • The only reason I didnt do it was cause this page had a larger number of view as opposed to the other one. – evolutionizer Aug 25 '15 at 19:40
  • @SteveRobillard I also dont think I have the rep required to do so – evolutionizer Aug 25 '15 at 19:46
  • Flagging a post only takes 15 rep. Deciding what to do about it is the job of the moderators - so the number of views is irrelevant. Duplicate answers are automatically flagged by the system. They are a form of gaming the system. Therefore, I deleted the third one. – Steve Robillard Aug 25 '15 at 19:50
  • @SteveRobillard Thanks for the information and forgive my ignorance. I have there for flagged the previous question as duplicate. – evolutionizer Aug 25 '15 at 19:53
3

if you use rc.local file, this may be helpful for troubleshooting. You can add logging lines to log errors (stderr) and command output (stdout) into log file. According to this example that file saves in /tmp/rc.local.log

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

exec 2> /tmp/rc.local.log      # send stderr from rc.local to a log file
exec 1>&2                      # send stdout to the same log file

# Your other commands...

exit 0

Read more

Tharanga
  • 131
  • 3
3

I'm really surprised djb's daemontools is not mentioned here. Daemontools does proper process supervision and you can add cool features like automatically rotated logging. TL;DR if you're not familiar with any of this, your process will be restarted every time it fails and start automatically when your Pi turns on. This is great if you wrote a bad python program that has failure modes but you don't want it to just die if an error is encountered.

Install:

sudo apt-get install daemontools daemontools-run

Then follow steps to create daemonized processes:

It's mostly as simple as copying a run script into /etc/service/<my_custom_service_name> Another perk: you can run as any user or root! Details in the link.

FWIW I had a Pi project where I had 3 different python processes (each had an execution loop using CPU time so by using 3 processes I allowed each process to leverage 1 CPU core). Daemontools allowed me to make sure all 3 would automatically run and stay running after I plugged in the Pi.

Sam
  • 131
  • 2
2

To use a .py file, just put the line #!/usr/bin/python at the very start of your file. Then make it executable with chmod +x filename. Next, add the line /path/to/file.py & to /etc/rc.local before the exit 0 line (swapping /path/to/file.py with the path to your script). This will make your python script execute at the end of boot.

Will
  • 380
  • 4
  • 17
1

these solutions didn't work for me trying to start a python script with running Feh. The following worked. It starts a script after login.

Open a terminal session and edit the file

sudo nano /etc/profile

Add the following line to the end of the file

/home/pi/your_script_name.sh

replace the script name and path with correct name and path of your start-up script. Save and Exit

Press Ctrl+X to exit nano editor followed by Y to save the file.

Here's what my script.sh looked like:

#!/bin/sh
cd /
cd home/pi/
sudo python your_python_sript.py &
exit 0
cd /

I think I made both the script.sh and script.py executable using the chmod

sudo chmod +x home/pi/your_script_name.sh
sudo chmod +x home/pi/your_python_script.py
hydronics
  • 21
  • 3
1

Here's an even easier method that worked for me. Modify the autostart in LXDE.

Open a terminal and edit the autostart file as follows:

sudo nano /home/pi/.config/lxsession/LXDE-pi/autostart

add the following line of text to the bottom(modify the path as needed to where your example.py is located)

@/usr/bin/python /home/pi/example.py

ctr-x, and save. You may need to make the python script executable as follows:

sudo chmod +x /home/pi/example.py

reference for autostart in LXDE and reference for making python executable

hydronics
  • 21
  • 3