I think what's happening here is that the pgrep -f "/usr/bin/nmon"
is also matching the shell running that command, since it will find the string "/usr/bin/nmon" in the full command-line and you specified -f to look for the string in the whole command-line (and not only the process name...)
There are many things incorrect in your script:
ps -aux|pgrep -f "/usr/bin/nmon"
Or:
ps -aux|pgrep -f "/usr/bin/nmon" |awk "{print $2}"
That's all incorrect. pgrep works by itself, you don't need any pipes. ps ... | grep ...
is a thing, but pgrep looks for the pattern in the process list itself, so no ps
needed. You also don't need awk
to cut the fields, since pgrep already returns the PIDs only.
Then:
kill $pids
Don't use pgrep to find pids and then kill them with a separate command... Instead, just use pkill directly! pkill is pgrep's sibling which will find the processes and send them a kill signal. You can even see that pgrep and pkill share the same man page since they are so similar.
wait $pids
That doesn't work either... Because you can only call wait
on processes that are children of the current process. You can't call it on just any process. Considering you just opened this shell through ssh, you can't really wait on these processes that were already there...
So, in short: no pipes, just use pkill directly, omit -f (so it only matches the /usr/bin/nmon commands) and don't wait:
for host in "${hosts[@]}" ; do
ssh "$host" pkill /usr/bin/nmon
done
Easy!
I also fixed the shell quoting for you... In short: you want to double quote all variables that expand to a single word. Well, and the array there too.
I hope this helps!