0

I have a cluster of computers which are connected via passwordless SSH and I have written a utility which runs a command over the entire cluster. The way it does it is by picking up machines present in a file, looping over them while running the command specified via SSH.

Now I want to run a kill command over the cluster. The way I do this is by grep'ing the process IDs and then running the kill command like this:

kill -9 $(ps -ef | grep service_name | awk '{print $2}')

But when I run this command, it loops over one machine, executes the command, loops over the second machine and just exits without even executing the command. So the command finally ends up executing on only one machine.

I read about this a bit and found out that subshell commands cmd1 $(cmd2) run over SSH don't properly execute.

Can anyone provide me a workaround.

7

Actually command substitution, which is not just a subshell, works fine. Your problem is you want it executed on the remote system by the remote shell, because the processes you want to kill are processes on the remote system. So you have to quote it, which gets a bit clumsy, although you can drop the grep when you have awk. Two options are:

ssh user@remote "kill -9 \$(ps -ef | awk '/service_name/{print $2}')"
ssh user@remote 'kill -9 $(ps -ef | awk "/service_name/{print \$2}")'

However, a better solution for this problem on most Linuxes and some(?) other Unixes is pkill which does the whole job of search for processes running a particular command and kill them:

ssh user@remote pkill -9 service_name

Depending on how the process is launched, you might need to search against the full command line:

ssh user@remote pkill -f -9 service_name
5

Thou shalt not pipe grep into awk!

ps -ef | awk '/service_name/ { print $2}' | xargs kill -9

or

pkill service_name
  • Nice! I used to always pipe grep into awk :) – fanaugen Jun 4 at 7:12
1

Try:

ps -ef | grep service_name | awk '{print $2}' | xargs kill -9

You might want to test it first.

-2

I wrapped the command kill -9 $(ps -ef | awk "/service_name/{print \$2}") with a '`' character and ran it using my utility and it worked like a charm. So below is the final command:

`kill -9 $(ps -ef | awk "/service_name/{print \$2}")`
  • @terdon The process that I want to kill is not really registered as a service. pkill would still work on it? Suppose I am starting a process like elasticsearch, how would I kill it using pkill? – Punit Naik Apr 19 '16 at 9:46
  • @terdon I am asking this because pgrep elasticsearch does not list the pid of elasticsearch considering pkill internally uses pgrep. – Punit Naik Apr 19 '16 at 9:52
  • pkill has nothing to do with whether a process has been "launched as a service" (you mean init scripts?), it is designed to kill any process by name. Read man pkill to see how it works. In principle, pkill elasticsearch should be enough, as long as the name of the executable is elasticsearch. If it doesn't list it, try pkill -f. – terdon Apr 19 '16 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.