7

Having below sample script sample.sh

#!/bin/bash

if ps aux | grep -o "sample.sh" >/dev/null
then
    echo "Already script running"
    exit 0
fi

echo "start script"

while true
do
    echo "script running"
    sleep 5
done

In above script i want to check if this script previously running or not if running then not run it again.

problem is check condition always become true (because to check the condition require to run script) and it always show me "Already script running" message.

Any idea how to solve it?

5 Answers 5

10

You need a proper lock. I'd do using flock like this:

exec 201> /tmp/lock.$(basename $0).file
if ! flock -n 201  ; then
  echo "another instance of $0 is running";
  exit 1
fi

# cmds 

exec 201>&- 
rm -rf  /tmp/lock.$(basename $0).file

This basically creates lock for script using a temporary file. The temporary file has particular significance other than it's used to tell whether your script has acquired a lock. When there's an instance of this program running, the next run of the same program can't run as the lock will prevent it.

Sign up to request clarification or add additional context in comments.

9 Comments

I believe the lock file should not be removed. There is no need to delete it and if you delete it, there is a risk that you delete it while it is locked, which breaks the lock (because the lock remains, but the file will change).
Removing it at the the program is harmless as the lock will be released automatically once program exits. I tend to delete temps I create.
But it shows me error like ./sample.sh: line 3: /tmp/lock../sample.sh.file: No such file or directory flock: 201: Bad file descriptor
@Jayesh If script dies for whatever reason, the lock is still released. Lock file will be left alone (not removed) but that won't cause any problem.
+1. This is best approach, when I see it, I immediately refer @Blue Moon's code and update in an exist script I wrote before, which need the same function, but I did it with too long script.
|
1

For me will be safer to use a lock file , create it when process start and delete after completion.

Comments

1

Let the script record its own PID in a file. Before doing so, it first checks if that file currently contains an active PID, in which case it exits.

pid=$(< ${PID_FILE:?} || exit
kill -0 $PID && exit

The next exercise is to prevent race conditions when writing the file.

Comments

0

Try this, it gives number of sample.sh run by the user

ps -aux | awk -v app='sample.sh' '$0 ~ app { print $1 }' |grep $USERNAME|wc -l

Comments

0

Wtite a tmp file to the /tmp directory. have your script check to see if the file exists, if it does then don't run.

#!/bin/sh

# our tmpfile
tmpfile="/tmp/mytmpfile"

# check to see if it exists.
# if it does then exit script
if [[ -f ${tmpfile} ]]; then
echo script already running.
exit
fi

# it doesn't exist at this point so lets make one 
touch ${tmpfile}

# do whatever now.

# end of script
rm ${tmpfile}

2 Comments

What if my script accidentally killed ? So it will not going to remove tempfile.
You can either include the PID name in file name or write it in temporary file. In case process is crashed new process will have different PID.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.