3

So I have a bash scripts that does some things (pull from github, delete folders .. etc ..) pretty basic stuff. I usually run it whenever I need a new version of the web app on the server.

The thing is there isn't anything that stopping this script from running simultaneously by different people (almost all developers connect to this server and they execute the same command).

So far, it didn't happen that the script is run by more than 1 developer at a time.

How do I make sure that this script cannot be run if it's already running by another user? Folder locking or checking if the script is running by another user (is this doable?) something else?

All users that can run this script are sudoers.

EDIT: Well after checking my colleagues turns out that not all of them are using the script .. some of them are executing the commands by hand so I need to lock the folder itself.

Ali
  • 133

4 Answers4

5

flock - Manages locks from shell scripts

man flock

eg

flock -x lockfile -c command

X Tian
  • 10,463
2

Putting these line inside your script also works. (Sorry, I forgot I defined mutex as a function).

mutex() {
    if ( set -o noclobber; echo "$$" > "$1") 2> /dev/null; then
            trap "rm -f \"$1\"; exit \$?" INT TERM EXIT KILL
            return 0
    else
            return 1
    fi
}

mutex .LOCKFILE || { echo "Another instance of $0 still exists"; exit 1; }
doneal24
  • 5,059
1

Using a lock directory is a nice atomic operation:

lockdir="/tmp/lock.$(basename "$0")"

if ! mkdir "$lockdir" >&/dev/null; then
    echo "lock directory already exists" >&2
    exit 1
fi

...

# remember to clean up. Use `trap` for robustness
rmdir "$lockdir"
glenn jackman
  • 85,964
0

You could add some precursor code that checks whether an instance of your script is running. The check is based on your running

ps ax | grep bash | grep hello.sh

In this case, someone is running your script "hello.sh" and the process ID is 78775:

78775 s003  R+     0:02.40 bash ./hello.sh

If no one is running your script, the output line that gets returned is blank.

Your precursor code should be able to spot blank output when you run the ps command and prevent the script from running, either through stoppage or through a set or random delay - your choice.

In summary, you are running the meat of your script as a singleton.