2

I've got a python script I'm trying to install a rpm package on but when I send the command to install it doesn't wait for the command to finish before restarting the service. I've read a lot of forums about using recv_exit_status() but I don't think I'm using it right.

This is what I have:

#!/usr/bin/python

import paramiko, os
from getpass import getpass

# Setting Variables 
Hosts = [ '192.168.1.1', '192.168.1.2'] #IPs changed for posting
username = 'root'
print 'Enter root password on remote computer:'
password = getpass()
port = 22
File = 'Nessus-6.11.2-es7.x86_64.rpm'

for host in Hosts:
    print 'Finished copying files. Now executing on remote computer'

    #Setting up SSH session to run commands
    remote_client = paramiko.SSHClient()
    remote_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    remote_client.connect(host, username=username, password=password)

    InstallNessus = 'rpm -U --percent %s'%File
    stdin, stdout, stderr = remote_client.exec_command(InstallNessus)
    stdout.channel.recv_exit_status()
    lines = stdout.readlines()
    for line in lines:
        print line
    stdin, stdout, stderr = remote_client.exec_command('systemctl restart nessusd.service')

    remote_client.close()

I've tried using Fabric but I seem to be messing up my syntax somewhere.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992

2 Answers2

2

add get_pty=True This will wait until command execution completed. stdin,stdout,stderr = self.ssh.exec_command(command,get_pty=True)

Jeevan Chaitanya
  • 1,255
  • 11
  • 12
1

It's channel.recv_exit_status(), not stdout.channel.recv_exit_status().

However, since you are trying to run the same command over many servers, something like parallel-ssh is a better fit and much faster than paramiko, both sequentially and in parallel.

Code to do it is also much simpler, just:

from pssh.pssh2_client import ParallelSSHClient

hosts = ['192.168.1.1', '192.168.1.2']
_file = 'Nessus-6.11.2-es7.x86_64.rpm'
cmd = 'rpm -U --percent %s' % _file

client = ParallelSSHClient(hosts, user='<user>', password='<password>')

output = client.run_command(cmd)
for host, host_output in output.items():
    for line in host_output.stdout:
        print "Host %s: %s" % (host, line)
    print "Host %s exit code %s" % (host, host_output.exit_code)

restart_out = client.run_command('systemctl restart nessusd.service')
# Just wait for completion
client.join(restart_out)

See documentation for further information.

danny
  • 5,140
  • 1
  • 19
  • 31
  • Using what you posted but it seems to be doing the same. The script doesn't seem to wait for the rpm install to finish. I only get output of "Host 192.168.1.1 exit code 0". I'll keep looking through the documentation though. – Jeremy Livingston Nov 13 '17 at 16:03
  • Test your command first. If there is no output the command may not have executed or exited with nothing to do, eg if the RPM is already installed. – danny Nov 13 '17 at 16:08
  • I'm such a noob. I just realized I didn't put the full path in my file variable. I think that was my issue on all of my scripts. – Jeremy Livingston Nov 13 '17 at 16:27