LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 02-17-2006, 05:13 PM   #1
kushalkoolwal
Senior Member
 
Registered: Feb 2004
Location: Middle of nowhere
Distribution: Debian Squeeze
Posts: 1,249

Rep: Reputation: 48
to check instance of a script running


Hi,

I have a script called check.sh which does a bunch of things and generally takes 5-10 mins to process.I run it from the /root/check.sh location. Now I would like to know how can I prevent it to run when it is already running. In short how can I make sure that the user does not run the second instance(by mistake) of that script while it is already running.

How can I check this in the check.sh script itself? What lines will I have to write at the beginning of the script to achieve this.

Thanks
 
Old 02-17-2006, 05:18 PM   #2
satinet
Senior Member
 
Registered: Feb 2004
Location: England
Distribution: Slackware 11, Sabayon 3.1
Posts: 1,464

Rep: Reputation: 46
you could create a lock file. crude but works? or where u thinking of somehting more technical?
 
Old 02-17-2006, 07:02 PM   #3
kushalkoolwal
Senior Member
 
Registered: Feb 2004
Location: Middle of nowhere
Distribution: Debian Squeeze
Posts: 1,249

Original Poster
Rep: Reputation: 48
Quote:
Originally Posted by satinet
you could create a lock file. crude but works? or where u thinking of somehting more technical?
yeah some example which I can follow and implement in my own script.

thanks for the effort though...
 
Old 02-17-2006, 10:55 PM   #4
baldwonder
Member
 
Registered: Sep 2004
Location: Florida
Distribution: Slackware, VectorLinux, FreeBSD,Xubuntu
Posts: 69

Rep: Reputation: 15
I'm not entirely sure, but putting this code at the beginning of check.sh should do the trick:

Code:
#! /bin/bash

test=$(ps aux|grep check.sh|wc -l)

if [ $test -ne 0 ]; then
  exit
fi

.... rest of code for check.sh
it should check and see if check.sh is running. If it is, it will just exit without executing anything, otherwise it will execute the rest of the script.
 
Old 02-18-2006, 06:43 AM   #5
kushalkoolwal
Senior Member
 
Registered: Feb 2004
Location: Middle of nowhere
Distribution: Debian Squeeze
Posts: 1,249

Original Poster
Rep: Reputation: 48
Quote:
Originally Posted by baldwonder
I'm not entirely sure, but putting this code at the beginning of check.sh should do the trick:

Code:
#! /bin/bash

test=$(ps aux|grep check.sh|wc -l)

if [ $test -ne 0 ]; then
  exit
fi

.... rest of code for check.sh
it should check and see if check.sh is running. If it is, it will just exit without executing anything, otherwise it will execute the rest of the script.
.


Thanks baldwonder. I will try that and see how it goes. Thank you very much.
 
Old 02-18-2006, 11:56 AM   #6
satinet
Senior Member
 
Registered: Feb 2004
Location: England
Distribution: Slackware 11, Sabayon 3.1
Posts: 1,464

Rep: Reputation: 46
good idea, but even if there are no processes running "wc" reports one line.

try "ps -ef|grep -i sopnfgsdpajgsn |wc -l" and you will see what i mean.

so you might need to use:

if test $test -gt 1
then
exit 2
fi


this is because grep finds itself.

you could also do:

ps -ef|grep check.sh|grep -v grep|wc -l

or similar...
 
Old 02-18-2006, 12:06 PM   #7
alienDog
Member
 
Registered: Apr 2004
Location: Europe
Distribution: Debian, Slackware
Posts: 505

Rep: Reputation: 46
One possible simple locking method for scripts:

Code:
kill -0 `cat /var/lock/yourscript 2> /dev/null` 2> /dev/null && exit 1
echo $$ > /var/lock/yourscript
It tries to send 0 signal to the pid stored in the file /var/lock/yourscript. If the signal get's send, the script is running and another instance will exit. If not, the pid is stored to /var/lock/yourscript. kill -0 only sends the signal and does nothing else, so it can well be used for something like this.
 
Old 02-18-2006, 03:18 PM   #8
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by baldwonder
I'm not entirely sure, but putting this code at the beginning of check.sh should do the trick
I've tried something like this (`ps -A | grep -c " check.sh$"` -gt 1), but it doesn't work reliably from within the script itself. It works fine from another script, however. For some reason ps thinks there are 2 instances running when polled from within the script.

I use the lock file method. This is handy if you are running the script as a daemon; to terminate the daemon, design the script to stop if the lock file disappears, then design a kill script to remove the lock file. This is a much easier and safer way to terminate as opposed to finding the process number and killing it.

Here is an example: scroll down and look for the secure message interface example (mostly the 'receive' and 'kill' scripts.)
ta0kira

Last edited by ta0kira; 02-18-2006 at 03:20 PM.
 
Old 02-18-2006, 03:29 PM   #9
satinet
Senior Member
 
Registered: Feb 2004
Location: England
Distribution: Slackware 11, Sabayon 3.1
Posts: 1,464

Rep: Reputation: 46
i like the kill -0 option.

there will be 2 from within the script. 1 - the script itself 2 grep finding itself greppingg. so you would have to put gt 2. sorry i didnt think of that.

the kill way is more elegant.
 
Old 02-19-2006, 11:50 AM   #10
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by satinet
there will be 2 from within the script. 1 - the script itself 2 grep finding itself greppingg.
I would think it would show up as a grep and not a check.sh.

'kill 0' works fine if you are calling it from the same shell it was started in; what if it starts without a tty like in an rc, or if the process extends beyond the shell it was called in? I kind of think kill is a little sloppy anyway; it doesn't give the script a chance to exit its own way, kind of like turning off your power strip instead of shutting down your computer properly. I think it's meant to clean up messes left by processes that encounter something they can't work around and they end up hanging (and for real binaries which are designed to process a TERM signal.) Also, if you are writing or reading a fifo, you could hang another entirely separate process that's trying to use the other end of it.
ta0kira
 
Old 02-19-2006, 12:18 PM   #11
baldwonder
Member
 
Registered: Sep 2004
Location: Florida
Distribution: Slackware, VectorLinux, FreeBSD,Xubuntu
Posts: 69

Rep: Reputation: 15
So I realized I used the wrong ps option in my code above. If you use ps -e instead of ps aux, it will show up as code.sh and not as grep (grep will be there, but only as grep and not grep check.sh). Satinet is right, you would have to change the code to say

[code]
if [ $test -gt 1 ]; then
exit 0
fi
[\code]

since there will be one instance of the code running when you are checking for extras.
 
Old 02-19-2006, 02:16 PM   #12
alienDog
Member
 
Registered: Apr 2004
Location: Europe
Distribution: Debian, Slackware
Posts: 505

Rep: Reputation: 46
Quote:
Originally Posted by ta0kira
'kill 0' works fine if you are calling it from the same shell it was started in; what if it starts without a tty like in an rc, or if the process extends beyond the shell it was called in? I kind of think kill is a little sloppy anyway; it doesn't give the script a chance to exit its own way, kind of like turning off your power strip instead of shutting down your computer properly.
You didn't pay attention to how the locking actually works. It stores the pid of the script to a file. Then when another instance of the script is started, the new script tries to send signal 0 (=do nothing) to the pid stored in the file (i.e. previous instance of the script) using the kill command. If the signal gets send it means that the script is running and the new script will exit _cleanly_. ABSOLUTELY NOTHING HAPPENS TO THE ALREADY RUNNING SCRIPT. It's not "sloppy" in any way and there is nothing in this that can be compared to turning off power without a proper shutdown. Also starting the new script from another shell, without tty etc. is no problem, the locking still works fine.

I think you must be confusing kill -0 with kill 0? The latter sends SIGTERM (signal 15) to the process group. That won't work in this case. It needs a dash.

Quote:
Originally Posted by ta0kira
I think it's meant to clean up messes left by processes that encounter something they can't work around and they end up hanging (and for real binaries which are designed to process a TERM signal.)
You think wrong The kill command is quite different from SIGKILL signal that kills programs. It's just a way to send signals to processes, including things like telling the process to continue execution if it's stopped (SIGCONT, 18). Granted, the name of the command is not very well picked. You signal some stopped pid with command kill -18 [PID] and it resumes execution... How is that kill?

Furthermore, the only signal that doesn't allow programs to exit their own way is the forementioned SIGKILL (signal 9). All the other signals (including SIGTERM, 15 and SIGINT, 2, which is same as CTRL+C) can be handled using the trap command, from scripts as well as binaries. Signal 0 of course doesn't need to be handled as it does nothing...

Quote:
Originally Posted by ta0kira
Also, if you are writing or reading a fifo, you could hang another entirely separate process that's trying to use the other end of it.
I honestly don't see how this could happen???

Last edited by alienDog; 02-19-2006 at 03:01 PM.
 
Old 02-20-2006, 10:17 AM   #13
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,284

Rep: Reputation: 172Reputation: 172
ps | grep isn't really resilient.
for instance it will find 'vi check.sh'
It also seems faintly inelegant to me.

pgrep -x check.sh may work better.


I generally use a lock file myself.
t seems a common idiom so maybe it works?

Last edited by bigearsbilly; 02-20-2006 at 10:19 AM.
 
Old 02-21-2006, 04:03 AM   #14
satinet
Senior Member
 
Registered: Feb 2004
Location: England
Distribution: Slackware 11, Sabayon 3.1
Posts: 1,464

Rep: Reputation: 46
i wrote a script like this on hp ux:

MYSTATUS="$(UNIX95= ps -C $PROC -o pid= -o comm=)"
if [ -z "$MYSTATUS" ]
then
<do something>
fi

Although i doubt this would work on linux quite the same. anyway, this code avoids the whole grep issue. which is something to be mindful of on production/important servers/computers.

grep can give results that you dont expect. e,g someone could run another check related programme at the same time, which could throw a spanner in the works.
 
Old 02-23-2006, 05:51 PM   #15
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by alienDog
You didn't pay attention to how the locking actually works.
I do suppose you are right. For some reason I was thinking the call was intended to kill the script that was already running.
Quote:
Originally Posted by alienDog
I think you must be confusing kill -0 with kill 0?
Yes, also correct.
Quote:
Originally Posted by alienDog
You think wrong The kill command is quite different from SIGKILL signal that kills programs.
I think I was unclear. I noted that it sends the TERM signal to the process, which is normally handled by a POSIX binary, however a script does not have the functionality to process these signals, therefore if it was in a loop or the sort it would be killed before it could exit the loop and clean up after itself.
Quote:
Originally Posted by alienDog
I honestly don't see how this could happen???
Yes, you caught me again; I was trying to reply fairly fast and was thinking in the context of the script I cited earlier. What happens with that is one script gives another script the OK to write to a fifo, but if that script is killed mid-wait then the other script hangs because it thought it was OK to write to the fifo, but that changed after the OK went through.
ta0kira
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Obtain ip address and check for running process via Bash Script? xconspirisist Programming 10 09-12-2008 01:18 PM
How can I check to see if a script is running? slick_willie Programming 13 03-16-2007 10:18 AM
script to check if process is dead or running rspurlock *BSD 6 04-12-2004 11:32 PM
script to check if the service is running eyt Linux - Newbie 2 02-16-2004 07:27 AM
[script] check for a running process mikshaw Linux - Software 2 01-13-2004 08:33 PM


All times are GMT -5. The time now is 04:11 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration