views:

231

answers:

3

I am having a hell of a time trying to write a "kill all other daemon processes" function for use within a bash daemon. I do not ever want more than one daemon running at once. Any suggestions? This is what I have:

    #!/bin/bash

    doService(){
        while
        do  
        something
        sleep 15
        done
    }

    killOthers(){
        otherprocess=`ps ux | awk '/BashScriptName/ && !/awk/ {print $2}'| grep -Ev $$`

        WriteLogLine "Checking for running daemons."

        if [ "$otherprocess" != "" ]; then 
            WriteLogLine "There are other daemons running, killing all others."
            VAR=`echo "$otherprocess" |grep -Ev $$| sed 's/^/kill /'`
            `$VAR`
        else
            WriteLogLine "There are no daemons running."    
        fi
      }


      killOthers
      doService

It works some of the time, it doesn't others. There is almost nothing consistent.

+1  A: 

Could you try the old 'lock file' trick here? Test for a file: if it doesn't exists, create it and then startup; otherwise exit.

Like:

#!/bin/bash
LOCKFILE=/TMP/lockfile
if [ -f "$LOCKFILE" ]; then
        echo "Lockfile detected, exiting..."
        exit 1
fi
touch $LOCKFILE
while : 
do
        sleep 30
done
rm $LOCKFILE # assuming an exit point here, probably want a 'trap'-based thing here.

The downside is you have to clean-up lock-files from time to time, if an orphan is left behind.

Can you convert this to a 'rc' (or S*/K* script ?) so you can specify 'once' in the inittab (or equivalent method - not sure on MacOS) ?

Like what is described here:

http://aplawrence.com/Unixart/startup.html

EDIT:

Possibly this Apple Doc might help here:

http://developer.apple.com/mac/library/DOCUMENTATION/MacOSX/Conceptual/BPSystemStartup/Articles/StartupItems.html

monojohnny
I want to have the most recently called daemon the one that stays active. I'm not sure this solution would work for what I'm planning.
Andrew J. Freyer
+2  A: 

You've already eliminated the current process ID using grep -v so there's no reason to do it again when you issue the kill. There's also no reason to build the kill in a variable. Just do:

kill $otherprocess

But why not just use:

pkill -v $$ BashScriptName

or

pkill -v $$ $0

without any grep.

Then you can do:

if [[ $? ]]
then
    WriteLogLine "Other daemons killed."
else
    WriteLogLine "There are no daemons running."
fi
Dennis Williamson
I do not have the pkill option... the kill $otherprocess doesn't seem to work either.
Andrew J. Freyer
A: 

If you run your service under runit — the service mustn't fork into the background — you'll have a guarantee there is exactly one instance of it running. runit starts the service if it isn't running or if it quit or crashed, stops it if you ask, keeps a pidfile around.

Tobu
hmmm, unfortunately I do not have runit either. I am running a non-devloper (no xcode tools) vanilla OSX install.
Andrew J. Freyer
It's probably packaged somewhere, but I'll let osx users provide a link or an equivalent.
Tobu
Have edited my original post to reflect this as well :this Apple Dev doc looks promising: http://developer.apple.com/mac/library/DOCUMENTATION/MacOSX/Conceptual/BPSystemStartup/Articles/StartupItems.html
monojohnny
@monojohnny: I like that approach, you already have my +1
Tobu