This question already has an answer here:

I want to automate running a Python script. And I think I already know how to do that with a cron entry.

The problem is that I need this script to run again only if a previous one has finished.

The Python script reads from a .csv file (only the first record), and gives it as parameters for the script onward. Then this record is removed from that table (which is essentially like a list of runs that need to be done) and is moved to another table for finished tasks along with the result of the script.

So, because records are being deleted at every run, I need a following iteration of the script to start only if the previous one finished.

How/Can I do that under Ubuntu 16.04 LTS?


I tried scheduling the python script this way and installed run-one like that:

sudo apt-get update
sudo apt-get install run-one

# The below code is in crontab
* * * * * run-one python '/home/phdmonster/Downloads/nn course/my_code.py'

Aand, it doesn't work. No tasks are run.

Edit by Sergiy Kolodyazhnyy: Issue resolved in comments, also discussed in linked chat room; issue was with extra *, linked duplicate works as per OP's comments

marked as duplicate by muru, Jacob Vlijm, karel, Charles Green, Sergiy Kolodyazhnyy Jan 27 '18 at 17:53

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    A more elegant solution imo would be to not run the script form cron, but as a background proc. Then from python, making the decision is easy. Else you'd need to check for the process to exist, only run if not. – Jacob Vlijm Jan 27 '18 at 8:33
  • @JacobVlijm How do i do that? – Emil Filipov Jan 27 '18 at 15:42
  • For example (assuning the script is executable): if ! pgrep -f '/path/to/script.py'; then '/path/to/script.py'; else echo "running"; fi (or create a tiny script from it) but I believe the dupe-link offers a few more options. – Jacob Vlijm Jan 27 '18 at 16:00
  • @JacobVlijm Well, i tried with run-one, but if i include it in the crontab command i don't even get past saving the command in the file. I receive an error "crontab failed to install". If i remove the run-one part i can save the file and it still doesn't work. I can execute my script as shown above - python /path/script.py – Emil Filipov Jan 27 '18 at 16:05
  • Is your python script executable? Then python is not needed, if it has the shebang. – Jacob Vlijm Jan 27 '18 at 16:06

As you are using cron I suppose you start your script at regular intervals. Each run modifies a result file.

So the script can do the following at its start:

  • check if the result file exists (i.e. this is the first run)
  • if it does not, then create it
  • calculate the start time of the preceding run
  • check if the modification time of the result file is newer than this start time
  • if it is not it means the last run has not yet finished, therefore the script exits without doing anything

The first two items are there to get the process running. If you don't include them the first run will do nothing as it is waiting for a non-existing predecessor to finish.

  • This is unsafe, as the modification time can indicate modifications have been made, but it can't indicate that all modifications have been made and the file is closed. – Chai T. Rex Jan 27 '18 at 9:51
  • @ChaiT.Rex Well, i will construct the script to make the modifications of the file at the end. I mean, after that the script is finished, so it should be safe that way. – Emil Filipov Jan 27 '18 at 13:19

If you are starting your script from cron and want's to check the previous one has been terminated before starting the next one You might make your script create in some predefined place, a symlink to its representation in /proc (/proc/[PID]), and then erase it at the end.

You would then have to check if the link is broken before running it again, or check it's command line /proc/[PID]/cmdline if it is not broken, for the case a crash would have prevented the link to be erased, and another process would have appeared with the same PID (If the process is still running, the command line will have the expected content. If it's anything else, then it means it's just another process with the same PID).

If you just want to chain a list of scripts but only if the previous script gave no error, then, you probably do not need cron.

you might just use the && syntax to chain different scripts: the shell will test the return code of one script, and start the next one only if there was no error:

script1 && script2

If you want one script to be executed repeatedly, while there is no error, you can use the while syntax to execute it repeatedly until it returns a non zero return code.

while script; do true; done # here the true command, is just a "no operation"
  • This has the problem that if the process crashes and a new long-running process accidentally takes the old PID, the cron job won't run anymore, and it won't be clear why it's no longer running. – Chai T. Rex Jan 27 '18 at 10:02
  • Wrong @Chai T. Rex : that's the exact reason why I told him to check if the command line is the expected one if the link is not broken – Camion Jan 27 '18 at 10:30

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