LinuxQuestions.org
Help answer threads with 0 replies.
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 05-03-2003, 08:01 AM   #1
cmfarley19
Member
 
Registered: Nov 2002
Location: Central VA
Distribution: Ubuntu/Debian
Posts: 228

Rep: Reputation: 32
Only one instance of bash script...


I have an entry in my crontab as follows:

0,15,30,45 * * * * cd /home/user/seti; ./setitime.sh > /dev/null 2> /dev/null

It is set to launch a script (setitime.sh) that logs the time it takes my machine to process seti@home packets.
The script is as follows:

#!/bin/bash
# display the duration in a logical string
duration ()
{
totalsecs=$1
secs=$(($totalsecs % 60))
mins=$((($totalsecs % 3600) / 60))
hours=$(($totalsecs / 3600))

if [ $hours = 0 ] && [ $mins = 0 ]
then
result_str="$secs second(s)"
elif [ $hours = 0 ]
then
result_str="$mins minutes(s) $secs second(s)"
else
result_str="$hours hour(s) $mins minute(s) $secs second(s)"
fi

echo $result_str
}

# clean up old files
#rm -f time
touch setitime

echo "Seti packet started at `date`" >> setitime
START_DATE=`date +%s`

#Do some stuff
./setiathome -nice 1 -stop_after_process


echo "Seti packet finished at `date`" >> setitime
END_DATE=`date +%s`
echo "Seti packet duration = `duration $(($END_DATE - $START_DATE))`" >> setitime
echo "----------------------------------------" >> setitime
echo "" >> setitime

In normal operating mode multiple instances of setiathome will not run if an instance of setiathome is already running.

Is there a way to prevent multiple instances of my script from running?

The way I would like this to work is:
- cron launches setitime.sh.
- setitime.sh logs the start time to setitime, launhes setiathome (with the option to stop after processing)
- setiathome stops processing, setitime.sh logs the stop time to setitime.
- setitime.sh stops
- cron launches setitime.sh
- (repeat)
If cron attemps to start a second instance of setitime.sh, it aborts.

Here's what's happeneing:
- cron launches setitime.sh.
- setitime.sh logs the start time to setitime, launhes setiathome (with the option to stop after processing)
- 15 minutes pass and cron launches a second setitime.sh
- setitime.sh logs the start time to of the second seti@home to setitime.
- can't run 2 setiathome. second instnace of setiathome aborts.
- setitime.sh logs the stop time of 2nd setiathome to setitime.
- setitime.sh logs the duration of 2nd instance of setiathome to setitime (0 seconds)
- (repeat from step 3 every 15 minutes)

Any thoughts on how to only allow 1 instance of my bash script?
 
Old 05-03-2003, 08:06 AM   #2
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417

Rep: Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977
just check a ps output to see if it is already running

Code:
if [ `ps ax | grep -c setiathome` ] then
  ./setistuffhere
fi
 
Old 05-03-2003, 01:30 PM   #3
cmfarley19
Member
 
Registered: Nov 2002
Location: Central VA
Distribution: Ubuntu/Debian
Posts: 228

Original Poster
Rep: Reputation: 32
OK...
i've played around with this for a ilttle while. what I really need is for the test to pass when it DOES NOT find an instance of itself already running.
I've put this in a test script this works when setitime.sh is running.

#!/bin/bash
if [ `ps aux|grep -c setitime.sh` ]; then
echo "setitime.sh running"
fi

I need something like

#!/bin/bash
if [ `ps aux|grep -c setitime.sh` -eq 0 ]; then
echo "setitime.sh is not running"
fi

the above does not seem to work, nor have any variants I've tried.

Any ideas anyone?
 
Old 05-03-2003, 01:44 PM   #4
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417

Rep: Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977
you should ps against the actual seti program, not your script.

if [ ! `ps ax | grep setiathome` ] then

or

if [ `ps ax | grep -c setiathome` -eq 0 ] then

thinking about it, that ps command itself may well be counted in the grep command, so it might well always be at least one, not 0... not sure.
 
Old 05-03-2003, 02:23 PM   #5
cmfarley19
Member
 
Registered: Nov 2002
Location: Central VA
Distribution: Ubuntu/Debian
Posts: 228

Original Poster
Rep: Reputation: 32
Tried both variations. Neither worked. I finally got this to do what I want:
#!/bin/bash
foo=`ps aux | grep -c setiathome`
#echo $foo
if [ "$foo" -eq "0" ]; then
echo "setitime.sh is not running"
fi

The beauty of Linux... more than one way to skin a cat.

Thanks for your help.
 
Old 05-03-2003, 03:15 PM   #6
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417

Rep: Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977Reputation: 1977
hmm, not really, that's just doing things the long way round.
 
Old 05-06-2003, 11:53 AM   #7
turnip
Member
 
Registered: Jul 2002
Posts: 143

Rep: Reputation: 15
Code:
printERROR() {
        echo "ERROR:" $@ >&2
}

getPID() {
        if [ $# -lt 1 ]; then
        printERROR "Insufficient Arguments."
        return 1
fi
/bin/ps -ax | grep "$1" |grep -v grep | awk '{print $1;}'
}
I wrote functions just for that. ps always seems to exit on 1 on my machine here so I had to come up with another way. All you need yo do is feed getPID the script name you are looking for.
 
Old 05-06-2003, 01:42 PM   #8
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,370
Blog Entries: 55

Rep: Reputation: 3555Reputation: 3555Reputation: 3555Reputation: 3555Reputation: 3555Reputation: 3555Reputation: 3555Reputation: 3555Reputation: 3555Reputation: 3555Reputation: 3555
Thought I'd have a go at it too.
Called from top of script, no args necessary.
If you're on RH, "pidof" kinda equals pgrep.

checkRun0() {
if [ "$(pgrep -d "" -f $0)X" != \
"$(pgrep -d "" -f -n $0)X" ]; then exit 1; fi; }

checkRun1() {
procStr=( $(pgrep -d " " -f $0) )
case "${#procStr[@]}" in 1) continue;;
0|2|*) exit 1;; esac; }
 
Old 01-12-2018, 12:38 PM   #9
sayanarijit
LQ Newbie
 
Registered: Jan 2018
Posts: 1

Rep: Reputation: Disabled
https://github.com/sayanarijit/pidlock

pidlock -n sleepy_script -c 'sleep 10'
 
Old 01-12-2018, 01:01 PM   #10
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=14, FreeBSD_10{.0|.1|.2}
Posts: 4,664
Blog Entries: 6

Rep: Reputation: 2524Reputation: 2524Reputation: 2524Reputation: 2524Reputation: 2524Reputation: 2524Reputation: 2524Reputation: 2524Reputation: 2524Reputation: 2524Reputation: 2524
@sayanarijit:
You have replied to a 15 year dead thread, and although your script may be relevant you did not provide any description of your solution other than a link and command example.

If you wish to share your solution with current users please post to your own thread and provide relevant detail so that your post is complete and more useful to others.

Please see the Site FAQ for guidance in posting and forum participation.

And welcome to LQ!

Last edited by astrogeek; 01-12-2018 at 01:02 PM. Reason: typos
 
Old 01-13-2018, 02:25 AM   #11
MadeInGermany
Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 695

Rep: Reputation: 319Reputation: 319Reputation: 319Reputation: 319
Code:
if [ `ps aux|grep -c setitime.sh` ]; then
has a race condition; the grep command can immediately appear in the ps list and then grep finds itself and matches in its arguments.
Correct is, in the grep argument enclose (at least) one character in [ ]. Then it still searches the bare character, but the [ ] will appear in the ps list and will not match.
Because [ ] is special to the shell, the grep argument must be put in quotes.
In this case there is another glitch: the . matches any character, and should be escaped \. or put in a character set [.].
Take the latter - it also solves the race condition!
Last but not least, one can use the exit status, saves a subshell.
Code:
if ps aux | grep -wq "setitime[.]sh"; then
(This is even true after 15 years.)

Last edited by MadeInGermany; 01-13-2018 at 02:27 AM.
 
Old 01-13-2018, 04:41 AM   #12
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 10,543

Rep: Reputation: 3131Reputation: 3131Reputation: 3131Reputation: 3131Reputation: 3131Reputation: 3131Reputation: 3131Reputation: 3131Reputation: 3131Reputation: 3131Reputation: 3131
but nowadays you can use pgrep instead of ps | grep and that works quite well. Otherwise (in general) a lock file should be used in such cases.
 
  


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
Bash Script frankie_boy313 Linux - General 4 06-11-2004 02:50 AM
send automatic input to a script called by another script in bash programming jorgecab Programming 2 04-01-2004 12:20 AM
bash script - incrementing a filename in a script tslinux Programming 10 08-05-2003 11:58 PM
bash script prob: how can i tell the script that a 'dd' has finished? Frustin Linux - General 2 04-02-2003 05:34 AM
script in same instance Manish Linux - General 2 02-23-2002 12:03 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:31 PM.

Main Menu
Advertisement
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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration