2016-06-28 26 views
0

Wizards of stackoverflow。私はparamikoを使って.txtファイルからSSHにコマンドを読み込もうとしています。現在、ファイルから最初の行を読み込んで実行します。私が2番目の行に到達すると、EOFErrorがスローされ、終了します。 2番目のコマンドで印刷するかどうかを確認するためにチェックインを行いますが、実行されません。誰かがこの問題を私に助けて解決できるようになることを願っていました。Python 3でのSSHプログラミングparamiko、コマンド実行時のEOFError

にconfigure terminal

インタフェースは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") 

また、私は、出力から文字列を構築するためのeaser方法があることを言及する必要があります。 stdinstdout、およびstderrはファイルのようなオブジェクトです。 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") 

更新: あなたは、1つの行に

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) 

を複数のコマンドを持っていない場合1行に複数のコマンドがある場合は、それらを異なるコマンドの配列に分割するだけです。

+0

コードはファイルを読み込みますが、2つ以上のコマンドがある場合は最後のものだけを読み込みます。それは私のファイルの読書と関係があるかもしれませんが、私はこれを修正する方法が不明です。 – Aaron

+0

回答を更新します。 – Arnial

+0

コマンドを実行しようとするとエラーが表示されました。新しいコードで詳しく説明しました。ありがとう。 – Aaron

関連する問題