0

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?

  • 1
    creating a service in systemd is good for this sort of thing – Jaromanda X May 2 '19 at 22:56
  • would this work with two python programs I am running or does it need to be something else? – Michael H. May 2 '19 at 23:00
  • yes, this would work – Jaromanda X May 2 '19 at 23:10
3

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

| improve this answer | |
  • 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
0

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()

~

| improve this answer | |
  • It's written in Python. – Michael H. May 2 '19 at 23:02
  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.