0

script:

#!/usr/bin/env bash
set -e
set -u
set -x
set -o pipefail

hosts=(
    host1
    host2
)
for host in ${hosts[@]}
do
  ssh $host 'pids=$(ps -aux|pgrep -f "/usr/bin/nmon"); kill $pids; wait $pids 2>/dev/null'
done

with output:

+ for host in '${hosts[@]}'
+ ssh host1 'pids=$(ps -aux|pgrep -f "/usr/bin/nmon" |awk "{print $2}") ; kill $pids ; wait $pids 2>/dev/null'
Killed by signal 15.

I have used the wait to capture the signal, but still not work?
Any help will be appreciated!

Honghe.Wu
  • 109
  • 1
  • 4

1 Answers1

1

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!

filbranden
  • 652
  • 5
  • 9