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!
Advertisement
Answer
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