尝试执行命令时使用Python 3 paramiko、EOFError进行SSH编程

尝试执行命令时使用Python 3 paramiko、EOFError进行SSH编程,python,ssh,paramiko,Python,Ssh,Paramiko,stackoverflow的向导。我正在尝试使用paramiko将.txt文件中的命令读入SSH。当前,它将从文件中读取第一行并执行它。但当我到达第二条线路时,它会抛出一个EOFError并退出。我检查了第二个命令是否可以打印,但是没有执行。我希望有人能帮我解决这个问题。这是我的密码: from paramiko import client import logging import os #Clear the screen before starting the script os.syst

stackoverflow的向导。我正在尝试使用paramiko将.txt文件中的命令读入SSH。当前,它将从文件中读取第一行并执行它。但当我到达第二条线路时,它会抛出一个EOFError并退出。我检查了第二个命令是否可以打印,但是没有执行。我希望有人能帮我解决这个问题。这是我的密码:

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文件的内容如下:

配置终端

接口Gi0/9

描述测试接口


非常感谢您的帮助。

可能的错误。当前执行的
sendCommand
可能无法接收输出(或完全输出)

理由
exit\u status\u ready
是一种非阻塞方式,用于查找接收到的退出状态。脚本可能仍未读取输出的最后一部分。如果
recv\u ready
True
,则需要在
之后调用
recv

另外,我认为在while循环中检查
recv\u ready
不是一个好主意。这是一种非阻塞方法。因为它
,而
循环将无用地运行多次,只会浪费您的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" )
我还应该提到,有一种更简单的方法可以从输出构建字符串。您可以使用以下事实:
stdin
stdout
stderr
都是类似文件的对象

下面是一个更简单的示例,用于
stderr
(最好也阅读它):

更新: 如果一行上没有多个命令,那么

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 )

如果每行有多个命令,只需将它们拆分为不同命令的数组。

当前的
sendCommand实现有时不接收服务器输出。它与原始代码相同,还是与简化版本相同?@Arnial它与原始版本相同代码将读取文件,但是如果我有2个或更多命令,它将只读取最后一个命令。这可能与我在文件中的读取有关,但是,我不确定如何修复此问题。它在尝试执行命令时引发了一个错误,在我发布的新代码中有更详细的说明。谢谢
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 )