Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

help with a script - grep and ps -ef info

Status
Not open for further replies.

Soopa

MIS
Aug 27, 2004
14
0
0
US
My boss has asked me to write a script that will detect if a certian process is running, and if it isn't to send an email to our systems group to let us know.
I wrote the script so it looks for a process ID (PID) file and if the PID is not there, to send it. That doesn't work for him.
basically, this is for a webserver. The script should read in a list of the servers that should be running, then run a ps -ef|grep -q $servername
My problem is, I have never used grep -q. I am told I can use that to figure it out.
I am very new to shell scripting :)
Something like this ?:
Code:
for i in `cat /inet/tools/config/recycler.2live`
do
ps -ef|/usr/xpg4/bin/grep -q $i > $sucess
if success!=0
then
    echo "$i not found"
fi
done

Thanks
Paul
 
grep -q returns a value to indicate sucess or failure, but doesn't output something.
That's why you use a return in main in c++ / c.
Code:
int main (void)
{
  cout << "hello world";
  return 0;
}
I replaced your backticks with $(...), because backtiks are deprecated in linux-bash at last.

Code:
for i in $(cat /inet/tools/config/recycler.2live)
do
ps -ef|/usr/xpg4/bin/grep -q $i && echo "$i not found"
done

seeking a job as java-programmer in Berlin:
 
In your example, it will output "$i not found" every time, even if the server is running.
I'm using the KSH shell so, i use the back ticks when cat'ing the file.
so grep -q does do what I want...that is it will tell me if it finds the process running, and wouldn't it output that as a 1 or 0 or success or failure?

Paul
 
I ended up just using this:
Code:
for i in `cat /inet/tools/config/recycler.2live`
do
TEST=`ps -ef|/usr/bin/grep $i|/usr/bin/grep -v grep|wc -l`
    if [ $TEST = 0 ]
    then
        echo "Subject: A server on $HOST is down\n\n$i is not running on $HOST"|mail sysdev@Car-Part.com
    fi
done

I couldn't get grep -q to fill the variable TEST with its results.
 
One note about using ps with grep.

Code:
$ ps | grep bash
user 1001 ... bash
user 1002 ... grep bash
Since the "grep bash" command contains "bash", grep will grep itself out of the ps list (when it's running at the point the ps command looks at the running processes).


To avoid this, you can use:
Code:
$ ps | grep ba[s]h
user 1001 ... bash

That is, just specify one of the characters as a single-character character match.

I really haven't investigated why that works, but it appears to, and it seems to be a fairly common idiom.

Actually, it probably will not work if the program is being run in a directory containing a file named "bash"... Perhaps there's a more universal solution someone can suggest.

 
it works because the is how you can search for multiple items.
doing what I did:
|/usr/bin/grep $i|/usr/bin/grep -v grep
does a similar thing. first I grep for the $i, then I grep those results with a grep -v grep which means find everything as long as it doesn't include the word grep.

PAul
 
Yeah, that'll work.

But what would you do if the process you were grepping for was named, for example, aggrepple? [tongue]


I know how works in general, but not why it produces that result with grep on ps.

I presume that the shell tries to expand bah into a filename when it sees it (thus my comment that it probably wouldn't work when you actually have a file named "bash"). When it fails, like it normally will, it just leaves the glob the same and passes "bah" as an argument to grep, just like that. Then grep probably recognizes that as a common idiom for "not grepping myself" and tries not to do so.

But I went stupid there; my comments about the shell expansion are mostly irrelevant. You can just single-quote the "bah" and not have to worry about whether you have a file named bash.

Alternately, maybe it's just the timing involved. Since the shell has to try to get a filename match for bah before it starts grep, ps might get to run before grep even starts, hence ps won't see the grep process running.

I'm just speculating here, though. If anyone knows the real answer, enlighten me, please.


Here's a more universal solution I thought of:
Code:
ps | ( sleep 2; grep bash )

Unless you have a really slow ps, or get really unlucky, you will never have grep grepping itself.
 
[tt]ps -C ps[/tt] should always find a process named "ps." ps is running when ps runs, after all.

Good solution for anything else, though.
 
Hi Paul,

Going back to your original question/problem:
>>> My problem is, I have never used grep -q. I am told I can use that to figure it out.

grep -q only returns the status (success is 0, failure is 1) of a "search". No output is sent to STDOUT or STDERR. So just test $? for sucess or failure, as follows (using your code):
Code:
for i in `cat /inet/tools/config/recycler.2live`
do
  ps -ef | /usr/xpg4/bin/grep -v grep | /usr/xpg4/bin/grep -q $i
  if [ $? -ne 0 ]
  then
    echo "$i not found"
  fi
done

For info, virtually every unix command produces a status (success is 0, failure is non-zero) which can be tested by checking $?. But for instance, if you pipe the above "grep -q $i" through "grep -v grep" then $? will always show a success because "grep -v grep" (the last unix command to be performed) was successful.

I hope that helps

Mike.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top