Page 1 of 1

Running a python script at startup

Posted: Sat Mar 12, 2016 2:09 am
by ChromeBlue
Yes I am a noob to both the Pi and Linux but have become pretty well versed at Python. I created RoboCoop that automates nearly everything but putting the fresh eggs in my fridge. The problem is I cannot for the life of me figure out how to run the script on boot.

I have read hundreds of forum posts and scores of web pages on this topic and I still can't get it to work. Could somebody please walk me thru this in plain english and not condescending Linux know-it-all acronym speak.

Using latest version of Wheezy, wifi dongle, pi cam on a Pi B. Simple setup. Boots and runs fine after manually starting script.
The Pi is dedicated to RoboCoop and runs nothing but what is needed to perform coop automation and remote desktop.

Thanks much!

Re: Running a python script at startup

Posted: Sat Mar 12, 2016 12:25 pm
by JimmyN
There are several ways to run a script at boot. You could add it to crontab.

I'll assume you're using Python2, and need "sudo" to run it from the command line, so we'll add it to roots crontab.

Code: Select all

sudo crontab -e
Add this line at the bottom

Code: Select all

@reboot /usr/bin/python /path/to/your/script.py

Re: Running a python script at startup

Posted: Sat Mar 12, 2016 1:47 pm
by quinness
Next suggestion to start it is systemd. make a new file in /etc/init.rd, e.g. MyRoboCoop

Code: Select all

sudo nano /etc/init.d/MyRoboCoop
Paste following in that file, maybe change the location of your RoboCoop.py file.

Code: Select all

#!/bin/sh
#
# description: Starts and stops the MyRoboCoop daemon
#
### BEGIN INIT INFO
# Provides: MyRoboCoop
# Required-Start: $network $syslog $remote_fs
# Required-Stop: $network
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: MyRoboCoop daemon
# Description: Start or stop the MyRoboCoop daemon
### END INIT INFO

ROBOCOOP_BIN=/home/pi/path/to/MyRoboCoop.py
test -x $ROBOCOOP_BIN || { echo "$ROBOCOOP_BIN not avaible";
        if [ "$1" = "stop" ]; then exit 0;
        else exit 5; fi; }

RETVAL=0

case "$1" in
  start)
        echo -n "Starting MyRoboCoop daemon "
        sudo -u pi $ROBOCOOP_BIN  # Add your parameters after
        ;;
  stop)
        echo -n "Shutting down MyRoboCoop daemon "
        /sbin/killall $ROBOCOOP_BIN
        ;;
  restart)
        $0 stop
        $0 start
       # rc_status
        ;;
  status)
        echo -n "Checking for MyRoboCoop service "
#        /sbin/checkproc $ROBOCOOP_BIN
       # rc_status -v
        ;;
  *)
        echo $"Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}"
        exit 1
esac
Enable this, by making it executable and add it to system d

Code: Select all

sudo chmod +x /etc/init.d/MyRoboCoop
sudo systemctl enable MyRoboCoop
sudo systemctl daemon-reload
For this to work, your /home/pi/path/to/MyRoboCoop.py needs to be executable and start with

Code: Select all

#!/usr/bin/python

Re: Running a python script at startup

Posted: Sat Mar 12, 2016 2:21 pm
by DirkS
quinness wrote:Next suggestion to start it is systemd.
That's not really using systemd. Part of it is legacy stuff.
See http://www.raspberrypi-spy.co.uk/2015/1 ... g-systemd/

Re: Running a python script at startup

Posted: Sat Mar 12, 2016 9:01 pm
by ChromeBlue
JimmyN wrote:There are several ways to run a script at boot. You could add it to crontab.

I'll assume you're using Python2, and need "sudo" to run it from the command line, so we'll add it to roots crontab.

Code: Select all

sudo crontab -e
Add this line at the bottom

Code: Select all

@reboot /usr/bin/python /path/to/your/script.py

I have tried this but it did not appear to work. I just tried again doing exactly as you directed and it does not appear to have run. How do I know of the script is running or not before an action that takes place within the script is set in motion?

I'm not going to try the next suggestion until I get this one figured out. (But I have before tried it as well)

Thank you so kindly for your help.

Re: Running a python script at startup

Posted: Sun Mar 13, 2016 12:23 am
by ChromeBlue
JimmyN wrote:There are several ways to run a script at boot. You could add it to crontab.

I'll assume you're using Python2, and need "sudo" to run it from the command line, so we'll add it to roots crontab.

Code: Select all

sudo crontab -e
Add this line at the bottom

Code: Select all

@reboot /usr/bin/python /path/to/your/script.py
OK, that did not work. I had to manually start RoboCoop after door should have closed at 6:15 and did not.

I read over your next suggestion and I am LOST. This is exactly the experiences that I have had in the past.

Re: Running a python script at startup

Posted: Sun Mar 13, 2016 1:49 am
by evilkitty
i have been using /etc/rc.local

Code: Select all

chad@Z97K1LLER:~$ ssh pi@10.0.0.75 cat /etc/rc.local
#!/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.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
mkdir /tmp/ram
chmod 777 /tmp/ram
mount -t ramfs -o size=1M ramfs /tmp/ram
/usr/bin/python /usr/local/sbin/thermostat &
/usr/bin/python /usr/local/sbin/lcd &
/usr/bin/tvservice -o
exit 0

Re: Running a python script at startup

Posted: Sun Mar 13, 2016 12:19 pm
by JimmyN
Let's send some output to a file to see what's going on.

Code: Select all

sudo crontab -e
@reboot /usr/bin/python /path/to/your/script.py >> /home/pi/robocoop.log 2>&1
That will send both std and error outputs to a log file. Reboot and look in the "robocoop.log" file in your home directory, what does it contain?

Re: Running a python script at startup

Posted: Sun Mar 13, 2016 11:48 pm
by ChromeBlue
JimmyN wrote:Let's send some output to a file to see what's going on.

Code: Select all

sudo crontab -e
@reboot /usr/bin/python /path/to/your/script.py >> /home/pi/robocoop.log 2>&1
That will send both std and error outputs to a log file. Reboot and look in the "robocoop.log" file in your home directory, what does it contain?

I'm trying to understand this - I really am.
OK, I did this and rebooted. It created robocoop.log but it is empty. Nada, nothing in the file. I understand the >> redirect but what is the "2>&1"?

Re: Running a python script at startup

Posted: Mon Mar 14, 2016 12:08 am
by ChromeBlue
ChromeBlue wrote:
JimmyN wrote:Let's send some output to a file to see what's going on.

Code: Select all

sudo crontab -e
@reboot /usr/bin/python /path/to/your/script.py >> /home/pi/robocoop.log 2>&1
That will send both std and error outputs to a log file. Reboot and look in the "robocoop.log" file in your home directory, what does it contain?
I ran the crontab entry at the command line and got this error:
-bash: /home/pi/coop/coop.log: Permission denied

No idea what I've done wrong but it appears to be trying to write to the file but permission is denied?

I had to enter "sudo " before the "python" in order for the command line to work. Is this the problem - user pi is not sudo?

Re: Running a python script at startup

Posted: Mon Mar 14, 2016 2:19 am
by JimmyN
Using "2>&1" sends all output from the script to the log file. If the Python script had generated an error it would be in the log.

There are two crontabs, one for the user, and one for root. You used "sudo crontab -e" so the line was added in root's crontab and the script was run by root. Since root ran the script the log file that was created also belonged to root. That's why you got the permission denied, you were trying to add to a file that belonged to root, so you had to use sudo.

I'll assume the script runs from the command line, do you normally use sudo to start it?

Are you sure the script isn't running after a reboot?
After it boots you can check using

Code: Select all

ps aux | grep robocoop.py
When I used the command only the grep process was shown, no surprise there, if it's running you'll have two entries.

Code: Select all

jimmy     1882  0.0  0.2   4276  1844 pts/1    S+   22:03   0:00 grep robocoop.py
And of course if you're not using "robocoop.py" change that.

Re: Running a python script at startup

Posted: Mon Mar 14, 2016 2:35 am
by paul_tech
You have the directory coop in the path. Does that directory exist and does the user you're logged in as have write permission to it?

Re: Running a python script at startup

Posted: Mon Mar 14, 2016 2:40 am
by paul_tech
Another thing. If you run your program from the command line does it continue to run? If it runs once and exits then it will do the same thing when you start it using init.

Re: Running a python script at startup

Posted: Mon Mar 14, 2016 4:01 am
by ChromeBlue
JimmyN wrote:
I'll assume the script runs from the command line, do you normally use sudo to start it?

Are you sure the script isn't running after a reboot?
Yes the script runs from the command line. It runs forever once started. Hence the need to start it at boot in case power is lost, etc. It will start again automatically.

The script is now being run @reboot. I only know this because at 7:15 I got the txt msg from the coop that the door had closed.

So thanks for helping resolve that issue. Now, how can I get to that session to see any info the script prints? I use "screen" typically so when I SSH in I can switch to the session running the script but that doesn't seem to work any longer.

Thanks so much for your help. Very kind of you.

Re: Running a python script at startup

Posted: Mon Mar 14, 2016 3:09 pm
by ChromeBlue
JimmyN wrote: Are you sure the script isn't running after a reboot?
After it boots you can check using

Code: Select all

ps aux | grep robocoop.py
When I used the command only the grep process was shown, no surprise there, if it's running you'll have two entries.

Code: Select all

jimmy     1882  0.0  0.2   4276  1844 pts/1    S+   22:03   0:00 grep robocoop.py
And of course if you're not using "robocoop.py" change that.
pi@raspberrypi ~ $ ps aux | grep coop.py
root 2258 0.0 0.2 1760 1108 ? Ss 10:00 0:00 /bin/sh -c /usr/bin/sudo python /home/pi/coop/coop.py
root 2259 0.0 0.6 4588 2620 ? S 10:00 0:00 /usr/bin/sudo python /home/pi/coop/coop.py
root 2262 1.5 2.2 11496 8720 ? S 10:00 0:00 python /home/pi/coop/coop.py
pi 2764 0.0 0.5 3552 1908 pts/0 S+ 10:01 0:00 grep --color=auto coop.py


I rebooted just before running the ps aux. It looks like I have 3 copies running. Maybe the rc.local and other attempts are working? If so, holy crap. I don't even know all the things I've tried that didn't appear to work.

Re: Running a python script at startup

Posted: Mon Mar 14, 2016 3:37 pm
by rpdom
ChromeBlue wrote:pi@raspberrypi ~ $ ps aux | grep coop.py
root 2258 0.0 0.2 1760 1108 ? Ss 10:00 0:00 /bin/sh -c /usr/bin/sudo python /home/pi/coop/coop.py
root 2259 0.0 0.6 4588 2620 ? S 10:00 0:00 /usr/bin/sudo python /home/pi/coop/coop.py
root 2262 1.5 2.2 11496 8720 ? S 10:00 0:00 python /home/pi/coop/coop.py
pi 2764 0.0 0.5 3552 1908 pts/0 S+ 10:01 0:00 grep --color=auto coop.py


I rebooted just before running the ps aux. It looks like I have 3 copies running. Maybe the rc.local and other attempts are working? If so, holy crap. I don't even know all the things I've tried that didn't appear to work.
I doubt you've got three copies running. You will find that each of those lines is started by the previous one.

Try ps -ef | grep coop.py to get a different listing format. There you will see the PID and PPID (Parent PID) of each process and you'll see that the PPID of 2259 is 2258 and the PPID of 2262 is 2259.

Cron runs the /bin/sh. That runs /usr/bin/sudo and waits for it to finish. The sudo then runs your python instance and waits for that to finish.

Re: Running a python script at startup

Posted: Mon Mar 14, 2016 3:46 pm
by ChromeBlue
Ahhhhh. Gracious

Re: Running a python script at startup

Posted: Sat May 14, 2016 5:03 pm
by noob1
Thanks for the info on this, I've been trying so many different ways to get my script to run on boot. The crontab -e solution works, the script runs, but it doesn't write to a text file like it is supposed to. I have data getting streamed to an InitialState account and that is working fine. I also have a piece of script that will send me an email when temperature/humidity levels increase past a specified limit, but the data is also supposed to be sent to a text file for every reading and I also have a different piece that creates a text file with a timestamp for when the temperatue/humidity gets to a critical level and sends me an email, the email sends the contents of that text file. But no text files ever get written while the rest of the program seems to working as it should? Any ideas?

Re: Running a python script at startup

Posted: Sat May 14, 2016 5:19 pm
by stderr
noob1 wrote:Thanks for the info on this, I've been trying so many different ways to get my script to run on boot. The crontab -e solution works, the script runs, but it doesn't write to a text file like it is supposed to But no text files ever get written while the rest of the program seems to working as it should?
Permissions and environment issues can often cause problems in cron. Are you making assumptions in your code about those things that might not be correct when run with cron? Perhaps write the simplest script you can, just one that saves the environment and who is running the process to the file. Does that work? You probably can google for examples of doing that that you could try. Get that working, look at what you might be assuming that isn't right and expand to your original script in iterations.

Re: Running a python script at startup

Posted: Sat May 14, 2016 6:07 pm
by noob1
stderr wrote:
noob1 wrote:Thanks for the info on this, I've been trying so many different ways to get my script to run on boot. The crontab -e solution works, the script runs, but it doesn't write to a text file like it is supposed to But no text files ever get written while the rest of the program seems to working as it should?
Permissions and environment issues can often cause problems in cron. Are you making assumptions in your code about those things that might not be correct when run with cron? Perhaps write the simplest script you can, just one that saves the environment and who is running the process to the file. Does that work? You probably can google for examples of doing that that you could try. Get that working, look at what you might be assuming that isn't right and expand to your original script in iterations.
What do you mean to write a script that saves the environment and who is running the process to the file? The only part of the script that doesn't function is a simple write to text file....
test = open("AllTempHumTest.txt", "a")
test.write(str(datetime.now())+ "\n")
test.write("Humidity Inside Cabinet(DHT11(17)): {}%\n".format(s.humidity()))
test.write("Temperature Inside Cabinet(DHT11(17)): {}*C\n\n".format(s.temperature()))

Everything else works fine, same variables are used for values sent to InitialState account as well as registering the email notification.

Re: Running a python script at startup

Posted: Sat May 14, 2016 6:23 pm
by noob1
Thanks for the advice stderr, I realized the problem was the script was being run as root, the text files were being written to the root directory instead of the pi user directory. I added /home/pi/ when I called to open the text file to write to and this solved the problem.

Re: Running a python script at startup

Posted: Sat May 14, 2016 6:27 pm
by dasmanul
One assumption about the environment that often goes wrong in cron jobs is the current working directory: That might not be your home directory and hence file creation might fail due to permission problems. Try including the full path in your open statement.

@edit: I type too slow... ;)