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