Python:成功执行ping else打印错误,在Cisco Router中执行命令

时间:2014-01-02 09:15:30

标签: python output ping paramiko cisco

以下代码从文本文件中提取IP地址(Cisco Router)并执行上述命令并将结果输出打印到文件中。这里我试图首先使用PING测试设备的可达性,成功的ping响应命令应该执行,否则应该打印错误并移动到下一个主机。请帮我说明如何实现这一目标。我是新手。

这是我的代码,

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

4 个答案:

答案 0 :(得分:1)

理想情况下,您不必首先使用单独的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服务的其他问题

答案 1 :(得分:0)

您可以尝试使用在多台计算机上执行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()

答案 2 :(得分:0)

我回想一下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

答案 3 :(得分:0)

为什么你需要Paramiko模块或者如果python可以自己创建输入?

#!/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!')