2016-06-28 3 views
0

Wizards of stackoverflow. paramiko를 사용하여 .txt 파일에서 SSH로 명령을 읽으려고합니다. 현재는 파일의 첫 번째 행에서 읽고 실행합니다. 두 번째 줄로 가면 EOFError가 발생하고 종료됩니다. 두 번째 명령이 인쇄를 수행하는지 확인하기 위해 체크인을했지만 실행하지는 않습니다. 나는 누군가가 나를 도와주고이 문제를 해결할 수 있기를 희망했다.Python 3의 paramiko로 SSH 프로그래밍, 명령을 실행하려고 할 때 EOFError

구성 터미널

인터페이스 Gi0/9

설명 Test_Interface

모든 :

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) 

.txt 파일이 같은 것을 읽을 것 : 여기 내 코드입니다 도와 주셔서 감사합니다. 감사합니다.

+0

현재'sendCommand'의 구현은 서버 출력을받지 못합니다. 원래 코드 또는 단순화 된 버전과 동일합니까? – Arnial

+0

@Arnial 원래 버전과 동일 – Aaron

답변

0

가능한 버그. sendCommand의 현재 구현은 출력 (또는 전체 출력)을받지 못할 수 있습니다.

이유 exit_status_ready은 종료 상태를 수신하는 것을 차단하는 방법이 아닙니다. 출력의 마지막 부분이 여전히 스크립트에 의해 읽히지 않을 수 있습니다. recv_readyTrue 인 경우 while 다음에 recv으로 전화해야합니다.

또한, while 루프에서 recv_ready을 확인하는 것이 좋습니다. 비 차단 방법입니다. 그것 때문에 while 루프는 쓸데없이 여러 번 실행되어 CPU 사용량을 낭비하게됩니다. 나를 위해

이 버전 작업 :

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") 

은 또한 I 출력에서 ​​문자열을 구축 할 수 easer 방법이 있다는 것을 언급해야한다. stdin, stdoutstderr은 파일과 비슷한 개체라는 사실을 사용할 수 있습니다. stderr은 여기

간단한 예는 (너무 그것을 읽고 좋은 생각 일 수 있음) :

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") 

업데이트 : 한 줄 다음

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) 

를 여러 명령이없는 경우 한 줄에 여러 개의 명령어가 있다면, 다른 명령어의 배열로 나누십시오.

+0

코드가 파일을 읽지 만 2 개 이상의 명령이있는 경우 마지막 명령 만 읽습니다. 그것은 파일에서 내 독서와 관련이있을 수 있지만, 나는 이것을 고칠 수있는 방법을 확신하지 못합니다. – Aaron

+0

답변을 업데이트합니다. – Arnial

+0

내가 게시 한 새 코드에서 더 자세한 명령을 실행하려고하면 오류가 발생합니다. 감사. – Aaron

관련 문제