Python:在成功ping else打印错误时在Cisco路由器中执行命令
下面的代码从文本文件中获取IP地址(Cisco路由器),并执行上述命令,并将结果输出打印到文件中。在这里,我试图首先使用PING测试设备的可达性,成功PING时应执行响应命令,否则应打印错误并移动到下一台主机。请帮助我如何做到这一点。我是个新手 这是我的密码Python:在成功ping else打印错误时在Cisco路由器中执行命令,python,output,ping,paramiko,cisco,Python,Output,Ping,Paramiko,Cisco,下面的代码从文本文件中获取IP地址(Cisco路由器),并执行上述命令,并将结果输出打印到文件中。在这里,我试图首先使用PING测试设备的可达性,成功PING时应执行响应命令,否则应打印错误并移动到下一台主机。请帮助我如何做到这一点。我是个新手 这是我的密码 import paramiko import sys import os import subprocess with open('C:\Python27\Testing\Fetch.txt') as f: for line in
import paramiko
import sys
import os
import subprocess
with open('C:\Python27\Testing\Fetch.txt') as f:
for line in f:
line = line.strip()
dssh = paramiko.SSHClient()
dssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
dssh.connect(line, username='cisco', password='cisco')
stdin, stdout, stderr = dssh.exec_command('sh ip ssh')
mystring = stdout.read()
print mystring
f = open('C:\Python27\Testing\output.txt', 'a+')
f.write(mystring)
f.close()
dssh.close()
输入文件Fetch.txt如下所示
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.5
我浏览了整个论坛,获得了我想要的东西。。如果该列表中的所有IP地址都是可访问的,那么脚本就可以正常工作。但是,如果无法访问任何一个IP地址,则脚本将突然结束,而不继续下一个IP地址。我意识到我在这里做错了什么,我只需要一点点帮助就可以了。。。。。请帮忙
import paramiko
import sys
import os
import subprocess
dssh = paramiko.SSHClient()
dssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
with open('C:\Python27\Testing\Fetch.txt') as f:
for line in f:
line = line.strip()
with open(os.devnull, "wb") as limbo:
ip = line
result = subprocess.Popen(["ping", "-n", "1", "-w", "200", ip],
stdout=limbo, stderr=limbo).wait()
if result:
print ip, "Down"
else:
print ip, "Reachable"
dssh.connect(line, username='cisco', password='cisco')
stdin, stdout, stderr = dssh.exec_command('sh ip ssh')
mystring = stdout.read()
print mystring
f = open('C:\Python27\Testing\output.txt', 'a+')
f.write('\n' + ip + '\n' + mystring)
f.close()
dssh.close()
您可以尝试使用fabric,它是为在多台机器上执行SSH命令而设计的 这只是我拼凑的一个片段,但它应该告诉你该怎么做
from fabric.api import run, execute ,env
class Fetcher:
def __init__(self,hosts=[]):
env.hosts= hosts
env.warn_only = True # needed to not abort on pingtimout or other errs
def getclock(self)
run('sh clock')
def fetch(self):
results = execute(self.getclock,hosts=env.hosts)
if __name__ == '__main__':
hosts = loadfromtxt(hosts.txt)
f = Fetcher(hosts=hosts)
f.fetch()
我回忆起python线程的一个例子,在文档中或者在我读过的一本书(不记得源代码)中,它做了与您尝试做的类似的事情。像这样的方法应该会奏效:
import sys
import os
import subprocess
from threading import Thread
class Pinger(Thread):
def __init__ (self, ip):
Thread.__init__(self)
self.ip = ip
self.status = False
def __repr__(self):
return "Pinger for '%s' status '%s'" % (self.ip, self.status)
def run(self):
with open(os.devnull, "wb") as limbo:
# Changed the arguments because I don't have a windows ping.exe to test it on
result = subprocess.Popen(["ping", "-c", "2", "-q", self.ip],
stdout=limbo, stderr=limbo).wait()
if result:
# print self.ip, "Down"
self.status = False
else:
# print self.ip, "Reachable"
self.status = True
hosts = []
with open('Fetch.txt') as f:
for line in f:
host = Pinger(line.rstrip())
# print host
hosts.append(host)
host.start()
for host in hosts:
host.join()
if host.status:
print "Host '%s' is up" % host.ip
#### Insert your ssh exec code here ####
# dssh.connect(host.ip, username='cisco', password='cisco')
# etc.
else:
print "Host '%s' is down" % host.ip
理想情况下,您不必首先使用单独的if语句测试主机是否可ping..paramiko内置了大量异常检查..在套接字模块中使用此功能..您的程序可以以更干净的方式编写,而无需使用子进程
import paramiko
import socket
dssh = paramiko.SSHClient()
dssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ips = [i.strip() for i in open("C:\Python27\Testing\Fetch.txt")] # creates a list from input file
for ip in ips:
try:
dssh.connect(ip, username='cisco', password='cisco', timeout=4)
stdin, stdout, stderr = ssh.exec_command('sh ip ssh')
print ip + '===' + stdout.read()
ssh.close()
except paramiko.AuthenticationException:
print ip + '=== Bad credentials'
except paramiko.SSHException:
print ip + '=== Issues with ssh service'
except socket.error:
print ip + '=== Device unreachable'
这将捕获其他异常,如错误凭据和ssh服务的其他问题如果python可以自己做,为什么需要Paramiko模块或创建输入
#!/usr/bin/python
import os
hostname = raw_input('Enter the Router Name: ')
routers = hostname.split(',')
print routers
for hostname in routers:
response = os.system("ping -c5 " + hostname)
if response == 0:
print(hostname, 'is up!')
else:
print(hostname, 'is down!')
谢谢你的回复。我已对代码进行了一些更改,您可以就此提出建议。”[Errno 10060]连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立连接失败,因为连接主机没有响应“我收到了提到的错误,代码在此突然结束,相反,我只想让python打印为主机“Down”,然后继续检查下一个主机并执行命令。您可以用这种方式修复以dssh.connect()开头的部分缩进吗?它看起来好像失败了,因为ssh连接代码在for循环之外。通过这种方式,它总是在最终主机上执行,无论它是向上还是向下。我肯定它应该在else:Block里面太好了谢谢。你的建议奏效了……针对路由器等嵌入式设备的一个问题是:它们通常不会实现整个SSH协议
exec_command()
,当您在这里使用它时,只有当ssh router_ip“sh ip ssh”
也能工作时,它才会工作——如果您不能从OpenSSH客户端成功运行该命令(命令行上有命令,连接后没有输入),那么这个Paramiko代码也不会工作……如果这不起作用,您需要使用invoke_shell()
,并使用expect-like逻辑等待提示、发送命令字符串等@RyPeck解决了我的问题。@MZZ我会试试你的建议,然后再给你回复。谢谢。因为paramiko是一个SSH客户机,并且该命令希望通过SSH执行命令。Ping仅仅是OP试图做的事情的一半。这是一个古老的查询,在论坛成员的帮助下工作。谢谢