Nick Nick - 5 months ago 9
Linux Question

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?

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 variation: 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
Comments