Skip to content
Advertisement

Run shell script exactly once with cronjob

I have a cron job that calls a script that checks for updates once every hour. If there are updates, it will call update.sh, which in turn calls commands.sh. I would like each “new” commands.sh to be run exactly once.

I was thinking of writing to a file each time I run commands.sh with some unique ID of that file. Before running commands.sh, I check if the file contains the ID of commands.sh. If so, don’t run it.

Edit – more detail:

cronjob:

  • fetch from git repo, pull and merge if any changes
  • Run update.sh:

    #!/bin/sh
    ./commands.sh
    

I want ./commands.sh to run just once, because next hour, the cron will run again, pull from git, and run update.sh again. Is there some way for each unique ./commands.sh to run just once?

After writing that out, maybe the best way is just to only run update.sh if there was a change from the git repo?

This seems like overkill and hard to maintain. Is there a simpler way to write a bash script that only runs one time?

Advertisement

Answer

At the start of the commands.sh script do this:

if [ -f stampfile ]; then
    exit
if
touch stampfile

This checks for a file called stampfile (specify a path to anywhere convenient where this may be stored). If it’s there, just exit. If it’s not there create it with touch.

Then let the script do its thing.

A slight digression: This can also be used to avoid having two instances of a script running at the same time. The script would then rm -f stampfile at the end of its run.

In this case, if the script is killed, the stampfile will be “stale” (stamp present but script not alive). To detect a stale stampfile, put the PID of the script into it instead of touching it.

To check if there’s another instance running, and managing the stampfile:

if [ -f stampfile ]; then
    if kill -0 $(<stampfile) 2>/dev/null; then
        exit
    else
        rm -f stampfile    # stale
    fi
fi
echo $$ >stampfile

# rest of script

rm -f stampfile

User @CharlesDuffy points out that this way of managing the stampfile may be prone to PID reuse issues, i.e. that the PID in a stale stampfile might be that of a running process that has nothing to do with any of this. There is apparently a Linux utility called flock that allows you to do this in a more robust way.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement