Strange behavior of grep

Hi All,

I am facing a strange problem while grepping for a process. Here is the small script that i have written.
It will look for any process running with the parameter passed to the script.
If no process is running it should print appropriate message.

[oracle@server]$ cat t.ksh
#!/bin/ksh

set -x

sid=$1
sid_cnt=$(ps -ef|grep -w "$sid"|grep -v "grep"|wc -l)
echo $sid_cnt
if [ $sid_cnt -eq 0 ];then
        echo "sid not runing"
        exit 1
else
        echo "sid running"
fi

I executed the script with a parameter "abc". There is no process running as "abc". But the output of the script shows otherwise

[oracle@server]$ ksh t.ksh abc
+ sid=abc
+ ps -ef
+ grep -w abc
+ grep -v grep
+ wc -l
+ sid_cnt=1
+ echo 1
1
+ [ 1 -eq 0 ]
+ echo 'sid running'
sid running

When i run below command on command prompt, i get a different(desired) output.

[oracle@server]$ sid=abc
[oracle@server]$ ps -ef|grep -w "$sid"|grep -v "grep"|wc -l
0

Can you please help why the command is behaving differently when run in a shell script & when run on a command line.

Regards,
Veeresham

This is because of the ksh process itself when you execute the script
Should be:

sid_cnt=$(ps -ef|grep -w "$sid"|grep -v "grep" | grep -v "ksh" |wc -l)

A MR.Bean correctly notes it is because you use also "abc" on the command line. So that will end up in the process table. If you would use:

ksh t.ksh ab[c]

then it should also work.

1 Like

Thanks MR.Bean & Scrutinizer for rectifying issue with my code!

Regards,
Veeresham

The problem can be safely avoided with pgrep

#!/bin/ksh

#set -x

sid=$1
sid_cnt=$(pgrep -x "$sid" | wc -l)
#echo $sid_cnt
if [ $sid_cnt -eq 0 ];then
        echo "$sid not runing"
        exit 1
else
        echo "$sid running"
fi
1 Like

You can also use the -c flag of grep rather than piping the output to wc -l so you get something more like:-

ps -ef|grep -wc ab[c]

Robin

NB the shell matches ab[c] against the files in the current directory.
If a file name abc exists it will change ab[c] to abc , and the problem will be back.
Therefore, it needs to be quoted:

ksh t.ksh "ab[c]"
ps -ef|grep -wc "ab[c]"
1 Like

You're right of course, good point :b:

Excluding the record with the process ID of the script should also do the trick:

...| grep -v $$ |...

$$ can be a small number.
Better grep -vw $$ .
Also some shells can spawn sub processes with a different PID, without updating $$,
then the $$ would not match grep's PPID.