We're an ISO27001:2013 Certified Supplier

blog-post-featured-image

As Linux system administrators, we run scripts from time to time, often in an automated way (perhaps via cron). There are times when it is desirable to only ever run one copy of a particular script at a time.

For example, let’s assume we have a script that rsyncs some data to another system every hour (there are far better ways of carrying out backups, but that’s for another time). If, for some reason, that script takes more than an hour to run, you’ll end up with two versions of the script running. That may well cause both to run slowly, and an hour later you’ll have yet another version (and so on).

The fix is to use locking to prevent multiple versions of the script running at any one time. To see this in action, you’ll need two shell sessions running. Prepare a simple test script, mytest.sh:

#!/bin/bash
while :; do
    date
    sleep 1
done

Run this as follows:

$ flock -n /tmp/test.lock -c "./mytest.sh"

As you might expect, you’ll see the current date and time output once a second.

Now go to the second shell session and run exactly the same script. This time you’ll be returned immediately to the shell, and if you check you’ll see that the last command exited with an error status:

$ flock -n /tmp/test.lock -c "./mytest.sh"
$ echo $?
1

If you abort the script that’s running in the first session with ^C, you’ll find you can now run it in the second session.

Wrapping all this up, we can ensure that only one copy of a script runs at any one time:

#!/bin/bash
flock -n /tmp/test.lock -c "./mytest.sh"
if [ $? -eq 1 ]; then
    mail me@example.com -s "mytest.sh already running" < /dev/null
fi

This can (and should) be refined for production use, but the principle is sound.

Was This Linux Tip Useful?

Let us know in the comments below.