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.