1

I am trying to execute remote command using subprocess:

import subprocess
x=subprocess.Popen(['ssh','15.24.13.14', ' ps -ef | grep -i upgrade | wc -l'],stdout=subprocess.PIPE)
y=x.stdout.read()
print y
print '\n'
z=int(y)
print z

I need to get number of processes runing with 'upgrade' in their name. But for some reason, script is not executed well. I get message: "Warning: Permanently added '15.24.13.14' (RSA) to the list of known hosts." And then nothing happens. Where is the problem?

user5142625
  • 85
  • 1
  • 1
  • 9
  • 1
    I don't think you can do remote commands over ssh with `subprocess` call. This thread might help you: http://stackoverflow.com/questions/3586106/perform-commands-over-ssh-with-python. Apparently, paramiko is a good option for that. – cnluzon Jul 22 '15 at 08:52
  • I know that there is an option to do that with subprocess.Popen – user5142625 Jul 22 '15 at 08:55
  • There is no need for username and password because script is already located on some remote location which connects to '15.24.13.14' only by using commadn command:'ssh 15.24.13.14' – user5142625 Jul 22 '15 at 08:55
  • 1
    What you can do is replace grep with `touch something` so you can check if the command is executed. – Eric Levieil Jul 22 '15 at 09:06
  • https://docs.python.org/2/library/subprocess.html advises to use `communicate()` to read data from proccess. – Eric Levieil Jul 22 '15 at 09:09
  • I find also intriguing the fact that you get that warning message every time since it `permanently` adds the host to known hosts. Does your `~/.ssh/known_hosts/` file change at all? Also, I think there's something missing in your grep command, which file/output are you parsing? – cnluzon Jul 22 '15 at 09:10
  • Your code works fine for me. Do you have a valid ssh key for your host ? And where is the `ps` command before the `grep` if you want to get the number of process runing with 'upgrade' in their name ? – FunkySayu Jul 22 '15 at 09:21
  • Yep, ps is missing, I will add it. – user5142625 Jul 22 '15 at 10:07

2 Answers2

2

The problem is that if you are connecting for the first time via ssh to the given host, it asks you to add this host to the known hosts list and user has to confirm this by pressing 'y'. Since you didn't, than it hangs and does nothing.

You should either:

  • turn off host verification: ssh -o "StrictHostKeyChecking no" user@host
  • send 'y' to the ssh input, or
  • add this host manually to the known hosts, or
  • change the method of performing remote calls.
Buyuk
  • 1,094
  • 1
  • 8
  • 23
  • Acctually, I am not worried about that message, but my problem is that script does not print number of processess with 'upgrade' in their name running on server. – user5142625 Jul 22 '15 at 10:11
  • @user5142625 You are missing '|' between ps and grep in your code. Dont know if it is simply misspelled, or an actual error. The code worked for me without any error, after I've added '|' character. – Buyuk Jul 22 '15 at 10:18
  • tnx, I corrected it. I will check if code works again – user5142625 Jul 22 '15 at 10:43
1

Because you didn't specify any stderr to the subprocess.Popen, the standard error will be directly print to your display. This is why you will always have the Warning: Permanently added '<hostname>' (ECDSA) to the list of known hosts. message until you clearly redirect stderr to a subprocess.PIPE (or /dev/null)

Also, to avoid hosts file issues, here is a little trick (be careful with it, it's kind of dangerous) :

from subprocess import Popen, PIPE
p = Popen(['ssh', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'StrictHostKeyChecking=no', hostname, 'ps aux | grep -i upgrade | wc -l'], stdout=PIPE, stderr=PIPE)
result = int(p.communicate()[0][:-1]) # don't forget there's the \n at the end.

Why is it dangerous ? Because in case of MITM attack, you don't have any knowledge base of the remote, so you considere the attacker as your remote destination. Be careful about over-using this feature.

FunkySayu
  • 7,641
  • 10
  • 38
  • 61