5

I have a process that I want to kill remotely. I tried

ssh remotehost "kill -9 $(ps -aux | grep foo | grep bar | awk '{print $2}')"

but this returns the error

kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

However if I run the command within the quotation marks

kill -9 $(ps -aux | grep foo | grep bar | awk '{print $2}')

on the remote host it works fine. Am I missing something here?

0

3 Answers 3

8

The $(..) command substitution would fail as the $ is expanded by the local shell even before it is passed to the stdin of the ssh command. You either need to escape it or use here-strings.

Also the command inside the awk that prints $2 gets interpolated as a command-line argument. So we escape it to defer its expansion until the command is executed remotely.

With escaping,

ssh remotehost "kill -9 \$(ps -aux | grep foo | grep bar | awk '{print \$2}')"

or with here-doc

ssh remotehost <<'EOF'
kill -9 $(ps -aux | grep foo | grep bar | awk '{print $2}')
EOF

Also note that grep .. | grep .. | awk is superfluous. You can do the whole operation with awk alone. Or even better use pkill to get the process to kill directly by name.

4
  • ah, interesting. I thought it would ship the complete expression within the quotation marks just as it is. So the $ will be evaluated immediately?
    – chrise
    Jan 24, 2019 at 6:26
  • @chrise: In that case, it is preferred to use the second approach involving here-doc
    – Inian
    Jan 24, 2019 at 6:28
  • either way I try seems to not return. So if I run it from command line, it doesnt go back to the prompt. If I run it from a script it doesnt go to the next line. Do I need to somehow explicitly exit this?
    – chrise
    Jan 24, 2019 at 6:48
  • 1
    @chrise: You should use the here-docs carefully. There shouldn't be any leading spaces in the line after 'EOF', any leading spaces should be removed
    – Inian
    Jan 24, 2019 at 6:49
0

This worked for me to kill for a set of hosts:

for i in `cat hostlist`;do ssh -q $i kill `ssh -q $i ps -ef | grep <process name>|awk '{print $2}'`;done  
0

you can optionally do something like

ssh remotehost "killall -r 'foo.*bar'"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .