I've created a process monitor to check for the presence of a running process, and if found we need to check its parent to determine if it is acceptable or not, it's a security check basically. It works great when I look for running processes and gives me output that I expect. However, for some reason when no process is found, it's spitting out an empty line instead of "ok" like I would expect. I know that the variable rmanRUNNING is being populated with a 0 if no process is running, I've checked, so I'm not sure why the first if statement isn't just failing over to the else and then performing the echo "ok" line before closing. Any help will be GREATLY appreciated. See below:
#!/bin/bash
rmanRUNNING=`ps -ef|grep rman|egrep -v grep|wc -l`
if [ "$rmanRUNNING" -gt "0" ]
then
PPIDs=($( ps -oppid= $(pgrep rman)))
kshddPID=($(pgrep -f 'ksh.*/rman_dd.ksh'))
for i in "${PPIDs[@]}"
do
:
for j in "${kshddPID[@]}"
do
:
if [ "$i" == "$j" ]
then
result="ok"
else
result="bad"
break
fi
done
if [ "$result" == "bad" ]
then
break
fi
done
echo "$result"
else
echo "ok"
fi
I must be missing something simple, I just can't seem to isolate it, if I simplify this to be just the if with the current conditional and then an echo followed by an else and an echo, it seems to work right, so I feel it's something to do with the loops inside the main if that are causing some error that I don't see. Or, perhaps it has to do with a misunderstanding of how break works so I'm breaking out to a point where I echo an empty "result" variable and then terminating, I'm just not sure.
Thanks in advance!
The problem is that ps -ef | grep rman | grep -v grep
is matching the process name rman_check.sh
. So when you run your script, $rmanRunning
is not 0
, because it's counting itself.
Use pgrep
with the -x
option so that it matches the command name exactly, rather than looking for a substring.
#!/bin/bash
rmanRunning=$(pgrep -x rman | wc -l)
if [ "$rmanRUNNING" -gt "0" ]
then
PPIDs=($( ps -oppid= $(pgrep -x rman)))
kshddPID=($(pgrep -f 'ksh.*/rman_dd.ksh'))
for i in "${PPIDs[@]}"
do
:
for j in "${kshddPID[@]}"
do
:
if [ "$i" == "$j" ]
then
result="ok"
else
result="bad"
break
fi
done
if [ "$result" == "bad" ]
then
break
fi
done
echo "$result"
else
echo "ok"
fi
However, there's also a problem with your overall logic. If you have two rman_dd.ksh
processes and they each have an rman
child, you'll report bad
when you compare one parent with the other. A simpler way is to just sort the two PID lists and compare them.
PPIDs=$(pgrep -x rman | sort)
kshddPIDs=$(pgrep -f 'ksh.*rman_dd.ksh' | sort)
if [ "$PPIDs" = "$kshddPIDs" ]
then echo "ok"
else echo "bad"
fi