Script executable only for one person at same time

Hi

My question:
Is there a way to lock a script if its already running for other users?

Like if i want to start a script, that is running by another user, there will be a message: Hey, you cant start the script because its running by another user, try it later.

my idea was that the script creates a tmp-file, what will be deleted at the end of the script. If everyone starts the script, there will be a scan: does the tmp-file exist, if yes: error message, if no: you can start the script.

The problem of my idea is that if the script has a crash, the tmp-file still exist and nobody can start the script anymore.

Do you have another, probably a better idea how i can resolve this problem?

Best regards
Roger M.

2 possibilities:
trap various signals (eg, EOF, TERM, KILL and INT) and if they occur remove the lock file
or
Write your current PID to the lock file. On start, check if the file exists and if there is a process with that PID and if it's named the same as the script. If not, run, exit otherwise.

Here is one way to do that without temporary files.

ps -eaf | grep test.sh | grep -v grep

if [ $? = 0 ]
then
echo "Script already running"
fi

A better way to do that is at the start of the script do the following.

  • Check whether your script runs by using ps command.

For example,if your script name is script.sh,then check the following.

ps ajx | egrep "[0-9]+:[0-9]+[ ]*sh script.sh"|rev|cut -d ' ' -f 1 | rev

Store the above output in the variable and checks whether it is equal to script.sh.If it matched,don't run the process.Else,run the process.

Thank u all! Sounds good!
I'll try it!

Greez Roger

---------- Post updated at 02:40 PM ---------- Previous update was at 02:17 PM ----------

Are you sure that youre code is right? theres an error: rev: command not found

Do you know the mistake?

Thx Greez Roger

Hi DarkSwiss:

rev isn't required by posix, so it may not be on all systems.

By the way, just so you know, if it is very important that one and only one instance of the script be running at any instant, none of the above solutions will guarantee that. If the script is seldom run, you may never have a problem with them, but it is still possible for more than one instance to run.

vivekraj's solution is similarly affected.

Regards,
Alister

Hi alister

thank you for the information.
is there no way to guarantee that nobody starts the script while it is running?
its a cloning script for databases, so it must not be startet twice.
the script has to be locked or something like that.

Greez & Thx Roger

A quite safe mechanism for locking in a shell script is to create a locking directory. Call mkdir without the -p switch and if you succedd (exit code = 0) then your script can go on, or has to terminate otherwise.

But there still is the problem to remove the locking directory at program termination. If you are using ksh you can define a trap handler for the exit event like:

LOCKDIR=/tmp/mylock.dir
trap 'rm -rf $LOCKDIR' 0
if mkdir $LOCKDIR
then
    # go on
else
    print -u2 already running.
    exit 1
fi

Hi hergp!

Thank you for your help!
The script works, if i start the script while the script is running, there is the right message "script is running". But if i start it a second time, the mylock.dir directory is removed-> so i can start it though the script is already running. how can i prevent that the script removes the mylock.dir?

Do I have to copy my whole code instead of the "go on" comment?

Now, my code is under the if ... fi

Thank you

Greez Roger

Ah, I see. This issue can be corrected by undefining the trap in the else part of the if statement, like:

#!/bin/ksh
LOCKDIR=/tmp/mylock.dir
trap 'rm -rf $LOCKDIR' 0
if mkdir $LOCKDIR
then
    # go on
else
    print -u2 already running.
    trap : 0
    exit 1
fi

It's also possible, to move the first trap statement into the "go-on" part:

#!/bin/ksh
LOCKDIR=/tmp/mylock.dir
if mkdir $LOCKDIR
then
    trap 'rm -rf $LOCKDIR' 0
    # go on
else
    print -u2 already running.
    exit 1
fi

Hey hergp!

I have chosen the second solution. It seems to work correctly =D
Thank you for your help!

Who can mark this theard as resolved? or isnt it necessary?

Greez Roger