Reputation: 1395
I have a shell script with methods:
start(){
echo "Hello world"
}
stop(){
ps -ef|grep script.sh|grep -v grep|xargs kill
}
while [ "$1" != "" ]; do
case "$1" in
start)
start
;;
stop)
stop
;;
*)
echo $"Usage: $0 {start|stop}"
exit 1
esac
shift
done
I am running this script using this command: ./script.sh start
to call the start method.Now, I want to check if this process is already running and exit if it is already running. I have tried some solutions online but nothing worked. Someone please help.
The solutions I have tried were:
if [ -f /var/tmp/script.lock ]; then
echo "Already running. Exiting."
exit 1
else
touch /var/tmp/script.lock
fi
<main script code>
#some code
rm /var/tmp/script.lock
The other one is:
PID=$(ps -ef | grep script.sh|grep -v grep)
if [ -z $PID ]; then
echo "Process already running"
exit
fi
These solutions doesn't work and exit even when the process is just started.
Upvotes: 6
Views: 7331
Reputation: 544
Here my script hope useful.
#!/bin/bash
export JAVA_HOME=/usr/java/jdk1.7.0_25
checkpid()
{
echo $(ps -ef | grep "LiquidityWarning.jar" | grep -v grep | awk '{ print $2}')
}
start ()
{
if [ $(checkpid) ] ; then
echo -e "\n$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar is running (pid:$(checkpid))\n"
else
echo ""
printf "$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar is starting..."
cd /app/mservice/CBTK_new
/usr/java/jdk1.7.0_25/bin/java -jar LiquidityWarning.jar > /dev/null 2>&1 &
fi
}
stop ()
{
if [ $(checkpid) ] ; then
kill -9 $(checkpid)
echo -e "\n$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar stop success\n"
fi
}
status ()
{
if [ $(checkpid) ] ; then
echo -e "\n$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar is running (pid:$(checkpid))\n"
else
echo -e "\n$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar is not started\n"
fi
}
restart()
{
if [ $(checkpid) ] ; then
stop
sleep 2
start
else
echo -e "\n$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar is not started\n"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*)
echo -e "\nUsage: $0 {start|stop|status|restart|reload}\n"
exit 1
;;
esac
Upvotes: 1
Reputation: 780899
The .lock
file solution should work. The only problem with it is if the script exits due to an error, and doesn't remove the lock file. An improvement is to store the PID of the process in the file, and check whether that PID still exists.
if [ -f /var/tmp/script.lock ] && kill -0 $(cat /var/tmp/script.lock); then
echo "Already running. Exiting."
exit 1
else
echo $$ > /var/tmp/script.lock
fi
<main script code>
#some code
rm /var/tmp/script.lock
kill -0
doesn't actually send a signal to the process, it just tests whether it's possible to send a signal: the PID exists and you have permission to send signals to it (unless you're running as root, this means the process is running with your same userid).
There's still a remote chance that this could get a false positive, if the script crashes and then its PID gets reused by the same user. But PID reuse should take a long time, and the chance that it gets reused by the same user should be low.
There's also the chance that two copies of the script will start simultaneously, and they'll both see that there's no lock file. If you need to protect against that, you should use the lockfile
command to implement a mutex around the code that checks for the file.
Upvotes: 3