I have a Python script (worker.py) that I'd like to be running all the time. I searched for other options to make this work (such as daemonizing the process), but can't get that to work with my current Linux knowledge. So I figured that I could use cron to run pgrep to check if it was running, and if not, start it.

I've added a line to my crontab (crontab -e) as this:

* * * * * pgrep -lf worker.py || /usr/bin/python /home/debian/hypermaq/scripts/worker.py

Running pgrep -lf worker.py from the command line returns an empty line if the script isn't running, and returns the correct PID if it is started in the other SSH session. So that makes me think the command is fine.

However, this doesn't work from cron. I've tried to find more info by piping the output of the pgrep command (added >> /home/debian/templog.txt 2>&1), and I get a new PID on each line in that file. If I run the pgrep -lf worker.py command with sudo, I do get a PID as well, which I think is the command I am running with sudo itself.

I have enabled the logging for cron, and can see that it starts the job each minute. I read that cron has a minimal path definition, so I used absolute paths.

I'm not sure how to interpret what I see, and thus, why it doesn't work as I expect. One specific thing I don't understand is why running the same pgrep -lf worker.py command has no return when ran as regular user (and when the script isn't running), but returns a PID when ran with sudo, also when the script isn't running.

  • 2
    I don't think it is a duplicate: I want to run the second command if the first returns no process, but when ran from cron it returns a pid, even if the script isn't running. Mar 13, 2018 at 14:22
  • 2
    I think the issue is that cron spawns a shell to run your command, and the arguments of that shell are matched by pgrep since you are using -f Mar 13, 2018 at 14:31
  • 1
    ^What @steeldriver says pgrep matches the worker.pys in sh -c 'pgrep -lf worker.py || ...worker.py'. There are better ways to have only one instance of a cron command. See dupe.
    – muru
    Mar 13, 2018 at 14:33
  • 1
    Another option is to match processes with a regular expression that requires the Python interpreter in the first and the Python script in the second position: pgrep -f '^/usr/bin/python /home/debian/hypermaq/scripts/worker\.py'. Mar 13, 2018 at 14:39
  • While following the suggested duplicate and reading up, I found * * * * * ps -ef |grep worker.py | grep -v grep || /usr/bin/python /home/debian/hypermaq/scripts/worker.py seems to do what I want. Mar 13, 2018 at 15:00


Browse other questions tagged or ask your own question.