Process Detection and Conditional Branching . . .

Greetings!

First post for this newbie :slight_smile:

If anyone has a moment to spare, I have a quick question for the community. For the record, I'm running Xubuntu 12.04...

Based on a few hours' digging about, I've created an executable test script, "test.sh" which incorporates the following code:

#!/bin/sh

runSeq() 
{
    sleep 1
    if ps -ef | grep -v grep | grep "some-process-name" > /dev/null
    then
    zenity --warning
    holdSeq
    else
    runSeq
}
runSeq

holdSeq()
{
    sleep 1
    if ps -ef | grep -v grep | grep "some-process-name" < /dev/null
    then
    holdSeq
    else
    runSeq
}
holdSeq

The object is to check every second to determine if a certain process is running; and, if it is, fire off a warning dialog for the user to dismiss. The script is then to wait around in the background until the process has been closed by the user; at which time it returns to its original standby mode.

However, for the life of me, I can't seem to get the above code to work. Gotta be a drop-dead simple thing syntaxwise; but it simply has eluded me thus far...

Any suggestions for the noob?

Thanks a bunch!

I'm not sure I understand what you want to achieve with your script. Calling those functions recursively without an exit branch is not the right way. Some point in time that will blast the stack. Why don't you create one single loop with an exit condition, and in that loop you sleep, test for that process, and run zenity warning if condition met?
BTW, you second redirection seems wrong.

1 Like

Have you tried running the script in debug mode? Might help you figure out what's causing the issue.

sh -x test.sh
1 Like

Thanks, folks.

With the collective input, I got this to work well:

#!/bin/sh

runSeq() 
{
    sleep 1
    if ps -ef | grep -v grep | grep "some-process-name" > /dev/null
    then
    zenity --warning
    holdSeq
    else
    runSeq
    fi
}
runSeq

holdSeq()
{
    sleep 1
    if ps -ef | grep -v grep | grep "some-process-name" > /dev/null
    then
    holdSeq
    else
    runSeq
    fi
}
holdSeq

However, now I'm really concerned about what RudiC said: Will I wind up running off the stack with the above code? Seems like it's all just going about in a slow, quiet loop.

What am I missing :confused:

Thanks again --

Your calls to holdSeq and runSeq are not like goto statements they are function calls which push the previous state onto a stack the flow of control never reaches the end of either of these functions before calling another instance.

Consider this alternative:

runSeq()
{
 while :
 do 
   ps -ef | grep -q "ome-process-name" && zenity --warning
   while ps -ef | grep -q "ome-process-name"
   do
     sleep 1
   done
   while ! ps -ef | grep -q "some-process-name"
   do
      sleep 1
   done
  done
}
1 Like

@Chubler_XL:
Thanks for the heads up here. Good code...

"Thanks" for everyone, too :wink:

However, this raises one last question concerning the OP:
Out of curiosity, is there some way of resetting/clearing the stack in an instance like this with an explicit call?

Or, is there a garbage collection function which can be accessed and called on the fly???

Again, just a curious noob :rolleyes:

There is no magic function you can call to unwind a stack when your functions never return.

You could overlay the current process with a fresh copy of itself by replacing the lines at the end of your file:

    else
    runSeq
    fi
}
holdSeq

with:

    else
    exec $0
    fi
}

Note that the last line of this script will never be reached and can, therefore, be removed and not affect the behavior of this script.

Obviously, Chubler_XL's script is a much better approach. Unless each recursive call in your original script is replaced by an exec call, there is no guarantee that the appropriate state changes will occur to get you to an exec call before you run out of stack space.

1 Like

Thanks again; and have a great day :slight_smile: