Company Logo
Linux Sysadmin stuff

using lockfiles in shell scripts (BASH)

using lockfiles in shell scripts (BASH)

 

If you want to be 100% sure that only 1 process accesses a resource at the same time, you can use the command "lockfile". Lockfile creates a semaphore file which you have to remove at the end with "rm -f". Lockfile waits 8 seconds and then retries if the file already exists.

 

example (without lockfile):

{chilicode}

#!/bin/bash

if [ -e number.txt ]; then
echo "File exists"
else
echo "File does not exists. Create file now."
echo 1 > number.txt
fi

a=$(/usr/bin/tail -n 1 number.txt)

if [ $a -gt 1 ]; then
a=$(/usr/bin/tail -n 1 number.txt)
/usr/bin/expr $a - 1 >> number.txt
fi

if [ $a -lt 2 ]; then
a=$(/usr/bin/tail -n 1 number.txt)
/usr/bin/expr $a + 1 >> number.txt
fi

{/chilicode}

 

The file "number.txt" should only contain the numbers 1 and 2. But, if you now run the script 1000 times in parallel

{chilicode}

# for a in {1..1000}; do ./script.sh & done

{/chilicode}

You will end up with something like:

{chilicode}

# cat number.txt |sort -n|uniq
-1
0
1
2
3
4
{/chilicode}

 

Some people might be tempted to do something like a hand-made lockfile:

{chilicode}

#!/bin/bash

if [ -e number.txt ]; then
echo "File exists"
else
echo "File does not exists. Create file now."
echo 1 > number.txt
fi
lock=0;
if [ -e script.lock ];then
lock=1
fi

while [ $lock -eq 1 ]
do
if [ -e script.lock ];then
lock=1
else
lock=0
fi
done

touch script.lock


a=$(/usr/bin/tail -n 1 number.txt)

if [ $a -gt 1 ]; then
a=$(/usr/bin/tail -n 1 number.txt)
/usr/bin/expr $a - 1 >> number.txt
fi

if [ $a -lt 2 ]; then
a=$(/usr/bin/tail -n 1 number.txt)
/usr/bin/expr $a + 1 >> number.txt
fi

rm -f script.lock

{/chilicode}

 

In our example this does not really work. Because if there is a context switch between the test (if [ -e script.lock ]) and the actual lock (touch script.lock) you will still end up with a mess in number.txt.

 

solution with lockfile:

{chilicode}

#!/bin/bash

if [ -e number.txt ]; then
echo "File exists"
else
echo "File does not exists. Create file now."
echo 1 > number.txt
fi


lockfile script.lock

a=$(/usr/bin/tail -n 1 number.txt)

if [ $a -gt 1 ]; then
a=$(/usr/bin/tail -n 1 number.txt)
/usr/bin/expr $a - 1 >> number.txt
fi

if [ $a -lt 2 ]; then
a=$(/usr/bin/tail -n 1 number.txt)
/usr/bin/expr $a + 1 >> number.txt
fi

rm -f script.lock
{/chilicode}

 

pros:

  • 100% sure that no more than one script is allowed to access the file
  • less code

Add comment


Security code
Refresh

Main Menu




Powered by Joomla!®. Developed by: premium drupal templates ThemZa  Valid XHTML and CSS.