-   Programming (
-   -   Only one instance of bash script... (

cmfarley19 05-03-2003 09:01 AM

Only one instance of bash script...
I have an entry in my crontab as follows:

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

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

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

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

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
- logs the start time to setitime, launhes setiathome (with the option to stop after processing)
- setiathome stops processing, logs the stop time to setitime.
- stops
- cron launches
- (repeat)
If cron attemps to start a second instance of, it aborts.

Here's what's happeneing:
- cron launches
- logs the start time to setitime, launhes setiathome (with the option to stop after processing)
- 15 minutes pass and cron launches a second
- logs the start time to of the second seti@home to setitime.
- can't run 2 setiathome. second instnace of setiathome aborts.
- logs the stop time of 2nd setiathome to setitime.
- 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?

acid_kewpie 05-03-2003 09:06 AM

just check a ps output to see if it is already running


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

cmfarley19 05-03-2003 02:30 PM

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 is running.

if [ `ps aux|grep -c` ]; then
echo " running"

I need something like

if [ `ps aux|grep -c` -eq 0 ]; then
echo " is not running"

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

Any ideas anyone?

acid_kewpie 05-03-2003 02:44 PM

you should ps against the actual seti program, not your script.

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


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.

cmfarley19 05-03-2003 03:23 PM

Tried both variations. Neither worked. I finally got this to do what I want:
foo=`ps aux | grep -c setiathome`
#echo $foo
if [ "$foo" -eq "0" ]; then
echo " is not running"

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

Thanks for your help.

acid_kewpie 05-03-2003 04:15 PM

hmm, not really, that's just doing things the long way round.

turnip 05-06-2003 12:53 PM


printERROR() {
        echo "ERROR:" $@ >&2

getPID() {
        if [ $# -lt 1 ]; then
        printERROR "Insufficient Arguments."
        return 1
/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.

unSpawn 05-06-2003 02:42 PM

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; }

All times are GMT -5. The time now is 08:35 AM.