LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (http://www.linuxquestions.org/questions/linux-general-1/)
-   -   Killing processes remotely using SSH (http://www.linuxquestions.org/questions/linux-general-1/killing-processes-remotely-using-ssh-648871/)

ddenton 06-12-2008 01:16 PM

Killing processes remotely using SSH
 
Hello list. I have a script that remotely deploys code then kills a process so it can re-init using the new code. Here's the command I'm trying to get working from the script:

ssh deployer@192.168.0.104 'ERPMPROC=`ps -ef | grep top | awk '{ print $2}' | head -1` && kill $ERPMPROC'

In this case, just an example, it finds "top" and kills it. This command works locally (not using the ssh login part...), but when ssh'ing in from a remote machine, I get this error:

awk '{ print $2}' | head -1` && echo $ERPMPROC'

awk: cmd. line:2: (END OF FILE)
awk: cmd. line:2: syntax error

I'm sure the whole thing is failing because it only seems the first and second single quotes and ends the command at the second, instead of the fourth. I haven't had any luck in escaping the first set of single quotes.

Any help is appreciated...

ramram29 06-12-2008 02:38 PM

Don't use a variable. I don't think you can set variables remotely. Try this:

ssh deployer@192.168.0.104 kill $(ps -ef | grep top | awk '{ print $2}' | head -1)

jschiwal 06-12-2008 03:30 PM

Your grep command might catch more than you want, such as an argument containing "desktop". If you want to kill the top command you could:
Code:

kill $(ps -ef | awk '/ top$/{print $2}')
or use "killall top".

ddenton 06-13-2008 08:56 AM

Quote:

Originally Posted by ramram29 (Post 3182864)
Don't use a variable. I don't think you can set variables remotely. Try this:

ssh deployer@192.168.0.104 kill $(ps -ef | grep top | awk '{ print $2}' | head -1)

Thanks for the response. I gave your suggestion a shot, and the command seems to be looking locally instead of remotely. It fails with:
Code:

bash: line 0: kill: (8029) - No such process
Looking at the pid sequence on the local and remote machines, it looks like a pid from the local machine.

I tried using backticks instead of $() and this string simply getting the PID works:

Code:

ssh deployer@192.168.0.104 ``ps -ef | grep top | awk '{ print $2}' | head -1``
However when I try adding the kill command (sudo kill, since I'm not connecting as root) I get the following:

Code:

ssh deployer@192.168.0.104 sudo kill ``ps -ef | grep top | awk '{ print $2}' | head -1``
Password:********

kill: can't find process "ps"
kill: can't find process "-ef"

I think I found a very hurky way of doing this, but it isn't pretty. I tried running the remote grep for the PID and writing it to a file, hoping then I could use command sub to write the PID into a variable. Unfortunately, it writes the file locally, not on the remote machine. So I tried scp'ing the file to the remote machine, then use command sub to put the PID into a variable and use that variable to run kill:

Code:

ssh deployer@192.168.0.104 ``ps -ef | grep top | awk '{ print $2}' | head -1`` > process.pidfile
scp process.pidfile deployer@192.168.0.104:
ssh deployer@192.168.0.104 'ERPMPROC=`cat process.pidfile`; sudo kill $ERPMPROC'

This seems to work, but it introduces some complexity I'd rather not have. If you have any other suggestions on getting other options to work, I'd appreciate it...

ddenton 06-13-2008 09:10 AM

Quote:

Originally Posted by jschiwal (Post 3182928)
Your grep command might catch more than you want, such as an argument containing "desktop". If you want to kill the top command you could:
Code:

kill $(ps -ef | awk '/ top$/{print $2})'
or use "killall top".

Thanks for responding. I can't seem to get this syntax to work either. The single quote after the close paren is giving me the error. Running the command locally on the target machine works, but it doesn't work remotely. I moved the trailing paren to the outside and it doesn't error, but it doesn't create any output, it just logs me in.
Code:

ssh deployer@192.168.0.104 $(ps -ef | awk '/ top$/{print $2}')
Last login: Fri Jun 13 09:04:15 2008 from 192.168.0.2

Killall for my test using top does work, but the real-world application for this is a java process calling a jar file (the name for which is the string I'm grepping for). In this case the process running is java, and there's other java processes running that I can't kill. I haven't tested this exactly though...

Thanks again for the reply.

jschiwal 06-14-2008 07:06 AM

I transposed those characters when I typed them in.

For gnu's version of ps, there is a -C option where you can select just the instance of the command. Also you can use the "killall" command to kill a process by name:

I tried this out to quit a top process running. Keep in mind that killall will cause all instances of top to quit.
ssh hpmedia "ps -C top && killall top || echo top isn't running"

I think that this example is more readable then using awk to filter the output of ps.

---

Sorry, I missed the last line on your response, and used "killall" again.

allend 06-14-2008 10:05 AM

Have you looked at pgrep or pkill?
e.g. 'pgrep -f $ERPMPROC' should return the PID of the currently running process.

jflo 09-02-2010 07:35 PM

TRY:

for i in server1 server2 server 3
do
pid=$(ssh $i ps -ef |grep top | awk '{ print $2 }' | head -1)
echo $pid
ssh $i kill $pid
done

Andreii 12-30-2013 08:22 PM

Minor modification of
Quote:

Originally Posted by ramram29 (Post 3182864)
Don't use a variable. I don't think you can set variables remotely. Try this:

ssh deployer@192.168.0.104 kill $(ps -ef | grep top | awk '{ print $2}' | head -1)

Code:

ssh deployer@192.168.0.104 "kill \$(ps -ef | grep top | awk '{ print \$2}' | head -1)"
worked for me


All times are GMT -5. The time now is 06:36 AM.