I have tried adding it to the rc.local file but sometimes the program will launch on boot but won't stay open. Is there a way to have so when the program stops running that it gets relaunched?
try using systemd, the following is a simple service config, runs as user pi, will restart on failure (to a point, if it always fails immediately, systemd will not try to restart the process continually)
You'd create a file in /etc/systemd/system
- perhaps call it something like myservice.service
... the .service
is important
[Unit]
Description=Your Service
After=network.target
[Service]
User=pi
Group=pi
Type=simple
ExecStart=/home/pi/yourprogram.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
In this example, the service wont start until after network.target
is active - which, for my case was essential, as the above is based on a service I have running that requires network
availability
Go through systemd
documentation for the many possibilities regarding waiting for particular targets
you can use for Before, After and WantedBy, and Wants ... all sorts of configurations that allow you to control precisely when your service will run
Then to "install" and "start" the service
systemctl enable myservice.service
systemctl start myservice.service
you can stop the service at any time
systemctl stop myservice.service
and to disable it completely (i.e. so it wont start on reboot)
systemctl disable myservice.service
At which point you could delete the myservice.service
file you created earlier
This is an extremely basic example, but that is as much as you need to create a service that meets your requirement that it restarts if it fails
-
Is there a way to have it run as a sudo or root user? I need to run it usually as "sudo python datalogger.py". – Michael H. May 3 '19 at 13:57
-
I tried this and it didn't work. The program has an output and its not even running once. – Michael H. May 3 '19 at 21:54
-
oh, you need output to the terminal? rc.local would fail as often as this solution in that case – Jaromanda X May 4 '19 at 2:01
-
Its not output to terminal that I need, the program outputs to a csv file in my user folder. I know its not a permissions issue because it worked when I launch it manually. – Michael H. May 6 '19 at 15:18
-
then it may be a "current folder" issue - set the current folder as required in the code, or use full paths not relative ones – Jaromanda X May 6 '19 at 15:37
There are pre-done ways that I am sure someone will suggest, but if you like to do it on your own do this. I have no idea what language you wrote your program in, so this wont be specific, but general Idea
at the start of your program, have it look for a specific file ~/.myPIDfile
in this file there will (maybe) be a pid. If there is one, check if that process is still running, if it is, then exit.
if its not rewrite the file with your current pid.
Now the program can be started as often as you want, but if there is already one running, it will just exit.
then add
* * * * * /path/to/your/program >> /path/to/log/file 2>&1
to your cron job with
crontab -e
This will start the program every minute, but again your program is now smart enough to know if there is already one running, so you will only have a single instance running. If there is a crash, in the next minute cron will start it up again.
Edit: so in python, i grabbed this from here
def findProcess( processId ):
ps= subprocess.Popen("ps -ef | grep "+processId+"| grep -v grep", shell=True, stdout=subprocess.PIPE)
output = ps.stdout.read()
ps.stdout.close()
ps.wait()
return output
If the PID is running, this will return a string, and I think if its not running it will return None.
So a function to check the PID might work like this:
def checkPID:
try:
f=open("/path/to/pidFile","r")
except:
#no pid file, good to continue
return True
pid=f.read()
status=findProcess(pid)
if status is None:
#no line from grep, not running
return True
if len(status)<3:
#very short string, maybe a newline, but no process info=not running
return True
f.close()
f=open("/path/to/pidFile","w")
f.write(str(os.getpid()))
f.close()
return False
and at the start of your program you would do:
if checkPID:
exit()
~
-
-
Tired this and the program would only run its loop once and stop. But if I run it in terminal as sudo python myprogram.py it runs without issue. – Michael H. May 3 '19 at 21:55
-
make the program executable, chmod +x /path/to/program add '#!/usr/bin/env python' to the top of your program. Does your program need to be sudo'ed? – Chad G May 3 '19 at 23:59
systemd
is good for this sort of thing – Jaromanda X May 2 '19 at 22:56