What is the best way to ensure only one instance of a Bash script is running? [duplicate] What is the best way to ensure only one instance of a Bash script is running? [duplicate] bash bash

What is the best way to ensure only one instance of a Bash script is running? [duplicate]


Advisory locking has been used for ages and it can be used in bash scripts. I prefer simple flock (from util-linux[-ng]) over lockfile (from procmail). And always remember about a trap on exit (sigspec == EXIT or 0, trapping specific signals is superfluous) in those scripts.

In 2009 I released my lockable script boilerplate (originally available at my wiki page, nowadays available as gist). Transforming that into one-instance-per-user is trivial. Using it you can also easily write scripts for other scenarios requiring some locking or synchronization.

Here is the mentioned boilerplate for your convenience.

#!/bin/bash# SPDX-License-Identifier: MIT## Copyright (C) 2009 Przemyslaw Pawelczyk <przemoc@gmail.com>#### This script is licensed under the terms of the MIT license.## https://opensource.org/licenses/MIT## Lockable script boilerplate### HEADER ###LOCKFILE="/var/lock/`basename $0`"LOCKFD=99# PRIVATE_lock()             { flock -$1 $LOCKFD; }_no_more_locking()  { _lock u; _lock xn && rm -f $LOCKFILE; }_prepare_locking()  { eval "exec $LOCKFD>\"$LOCKFILE\""; trap _no_more_locking EXIT; }# ON START_prepare_locking# PUBLICexlock_now()        { _lock xn; }  # obtain an exclusive lock immediately or failexlock()            { _lock x; }   # obtain an exclusive lockshlock()            { _lock s; }   # obtain a shared lockunlock()            { _lock u; }   # drop a lock### BEGIN OF SCRIPT #### Simplest example is avoiding running multiple instances of script.exlock_now || exit 1# Remember! Lock file is removed when one of the scripts exits and it is#           the only script holding the lock or lock is not acquired at all.


If the script is the same across all users, you can use a lockfile approach. If you acquire the lock, proceed else show a message and exit.

As an example:

[Terminal #1] $ lockfile -r 0 /tmp/the.lock[Terminal #1] $ [Terminal #2] $ lockfile -r 0 /tmp/the.lock[Terminal #2] lockfile: Sorry, giving up on "/tmp/the.lock"[Terminal #1] $ rm -f /tmp/the.lock[Terminal #1] $ [Terminal #2] $ lockfile -r 0 /tmp/the.lock[Terminal #2] $ 

After /tmp/the.lock has been acquired your script will be the only one with access to execution. When you are done, just remove the lock. In script form this might look like:

#!/bin/bashlockfile -r 0 /tmp/the.lock || exit 1# Do stuff hererm -f /tmp/the.lock


I think flock is probably the easiest (and most memorable) variant. I use it in a cron job to auto-encode dvds and cds

# try to run a command, but fail immediately if it's already runningflock -n /var/lock/myjob.lock   my_bash_command

Use -w for timeouts or leave out options to wait until the lock is released. Finally, the man page shows a nice example for multiple commands:

   (     flock -n 9 || exit 1     # ... commands executed under lock ...   ) 9>/var/lock/mylockfile