2016-06-28 6 views
0

Assistenten von Stackoverflow. Ich versuche, Befehle aus einer TXT-Datei in SSH mit Paramiko einzulesen. Momentan liest es in der ersten Zeile der Datei und führt sie aus. Wenn ich jedoch zur zweiten Zeile komme, wird ein EOFError geworfen und beendet. Ich checke ein, um zu sehen, ob der zweite Befehl es zum Drucken bringt, und es wird jedoch nicht ausgeführt. Ich hatte gehofft, dass jemand in der Lage wäre zu helfen und dieses Problem mit mir zu lösen. Hier ist mein Code:SSH-Programmierung mit Python 3 paramiko, EOFError beim Versuch, Befehle auszuführen

from paramiko import client 
import logging 
import os 

#Clear the screen before starting the script 
os.system('cls') 

# Prompting for the user input config file 
filename = input('Input configuration filename, the file extension must be attached: ') 

# Creating the LOG file for the execution of the config file 
logFileName = "LOG" + filename[0:] 
try: 
    logging.basicConfig(filename= logFileName ,format='%(asctime)s %(message)s', level= logging.DEBUG) 
    print ("The file was created!") 
except IOError: 
    print ("File failed to create") 

logging.info("---------------------------------------------------------------------------") 
logging.info("NEW CONFIGURATION LOG ENTRY") 
logging.info("---------------------------------------------------------------------------") 


# Class for creating an SSH client, logging in, letting us write out commands, and close the client. 
class ssh: 
    client = None 
    def __init__(self, address, username, password): 


     print ("Connecting to server...") 
     logging.info('Connecting to server...') 

     self.client = client.SSHClient() 
     self.client.set_missing_host_key_policy(client.AutoAddPolicy()) 
     self.client.connect(address, username= username, password= password, look_for_keys= False) 

     logging.info("Address: " + address) 
     logging.info("Username: " + username) 
     print ("Connection successful!") 
     logging.info('Connection successful!') 

    def sendCommand(self, command): 
     if (self.client): 
      stdin, stdout, stderr = self.client.exec_command(command) 
      receiveData = b"" 
      while not stdout.channel.exit_status_ready(): 
       receiveData += stdout.channel.recv(1024) 

      if stdout.channel.recv_ready(): 
       received = stdout.channel.recv(1024) 
       while received: 
        receiveData += received 
        received = stdout.channel.recv(1024) 

      if receiveData: 
       print (str(receiveData, "utf8")) 

      else: 
       print ("stdout is empty") 
     else: 
      print ("Connection failed, check credentials and try again..") 
      logging.warning('Connection failed, check credentials and try again..') 

connection = ssh('0.0.0.0', 'test', 'test') 
with open(filename) as f: 
    for line in f: 
     print(line) 
     connection.sendCommand(line) 

Die TXT-Datei in etwa so lesen würde:

configure terminal

Schnittstelle Gi0/9

Beschreibung Test_Interface

Beliebig Hilfe wird sehr geschätzt, danke.

+0

Aktuelle Implementierung von 'sendCommand' einige Male nicht Serverausgabe erhalten. Ist es dasselbe wie im ursprünglichen Code oder in der vereinfachten Version? – Arnial

+0

@Arnial das gleiche wie die ursprüngliche Version – Aaron

Antwort

0

Möglicher Fehler. Die aktuelle Implementierung von sendCommand empfängt möglicherweise keine Ausgabe (oder volle Ausgabe).

Grund exit_status_ready ist eine nicht blockierende Möglichkeit zu finden, dass Exit-Status empfangen wird. Es ist möglich, dass der letzte Teil der Ausgabe immer noch nicht vom Skript gelesen wird. Sie müssen recv nach while anrufen, wenn recv_readyTrue ist.

Auch glaube ich nicht, dass die Überprüfung recv_ready in While-Schleife ist eine gute Idee. Es ist nicht blockierende Methode. Aus diesem Grund while Schleife wird nutzlos mehrere Male laufen, verschwenden nur Ihre CPU-Leistung.

Diese Version Arbeit für mich:

receiveData = b"" 
while not stdout.channel.exit_status_ready(): 
    receiveData += stdout.channel.recv(2048) 

if stdout.channel.recv_ready(): 
    received = stdout.channel.recv(2048) 
    while received: #received will be empty only when all data received 
     receiveData += received 
     received = stdout.channel.recv(2048) 

if receiveData: 
    print(str(receiveData, "utf8")) 
else: 
    print("stdout is empty") 

Auch soll ich erwähnen, dass es einleuchtende Weise Zeichenfolge von Ausgabe zu bauen ist. Sie können die Tatsache verwenden, dass stdin, stdout und stderr dateiähnliche Objekte sind.

Hier einfacheres Beispiel für stderr (kann es sinnvoll sein, es zu lesen):

data = "" 
for line in stderr: 
    #line in string already (probably will work only if locale is utf8) 
    data += line 

if data: 
    print(data) 
else: 
    print("stderr is empty") 

Update: wenn Sie nicht mehrere Befehle in einer Zeile dann

filename = input('Input configuration filename, the file extension must be attached: ') 
# define ssh class here (i'll skip it to make it shorter) 

connection = ssh('0.0.0.0', 'test', 'test') 
with open(filename) as f: 
    for line in f: 
     connection.sendCommand(line) 

haben Sie Wenn Sie mehrere Befehle pro Zeile haben, teilen Sie sie einfach in ein Array verschiedener Befehle auf.

+0

Der Code wird die Datei lesen, aber wenn ich 2 oder mehr Befehle habe, liest es nur die letzte. Es könnte etwas mit meinem Lesen in der Datei zu tun haben, aber ich bin mir nicht sicher, wie ich das beheben könnte. – Aaron

+0

Ich aktualisiere Antwort. – Arnial

+0

Es warf mir einen Fehler, wenn ich versuche, die Befehle auszuführen, detaillierter in neuem Code, den ich gepostet habe. Vielen Dank. – Aaron

Verwandte Themen