简体   繁体   English

Python:在成功的ping上在Cisco路由器中执行命令,否则打印错误

[英]Python: Execute a command in Cisco Router on successful ping else print error

The following code fetches IP address (Cisco Router) from a text file and executes the mentioned command and prints the resultant output on to a file. 以下代码从文本文件中获取IP地址(Cisco路由器)并执行上述命令,并将结果输出打印到文件上。 Here am trying to first test the reach-ability of the device by using PING, on successful ping response commands should be executed else should print an error and move to the next host. 这里尝试通过使用PING首先测试设备的可达性,在成功执行ping响应命令后,应执行该命令,否则应打印错误并移至下一个主机。 Please help me on how to achieve this. 请帮助我如何实现这一目标。 I am a newbie. 我是新手。

Here is my code, 这是我的代码,

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

Input file Fetch.txt looks like this, 输入文件Fetch.txt看起来像这样,

10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.5

I scoured through the forum and achieved just about what I am looking for.. If all the IP addresses are reachable in that list, the script works just fine. 我在论坛上进行了搜索,并大致达到了我要寻找的内容。如果该列表中的所有IP地址都可以访问,则脚本可以正常工作。 But if any one of the IP address is unreachable then the script ends abruptly without proceeding to the next IP address. 但是,如果任何一个IP地址都无法访问,则脚本会突然结束,而不会继续处理下一个IP地址。 I realize that am doing something wrong here, I just need that little bit of help to get this working..... Please help out. 我意识到这里做错了,我只需要一点帮助就可以使它正常工作.....请帮忙。

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

You ideally don't have to test if a host is pingable first using a separate if statement..paramiko comes inbuilt with a lot of exception checking ..using this along the socket module..your program can be written in a cleaner fashion without having to use subprocesses.. 理想情况下,您不必使用单独的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' 

this will catch other exceptions like bad credentials and other issues with ssh service 这将捕获其他异常,例如错误的凭据和ssh服务的其他问题

You could try using fabric which is made for executing SSH commands on multiple machines. 您可以尝试使用用于在多台计算机上执行SSH命令的结构。

This is just a snippet i threw together but it should show you the way to go. 这只是我汇总的一小段,但它应该向您显示前进的道路。

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

I recall an example of python threading, either in the docs or in a book I read (don't remember the source) that does something like what you're trying to do. 我在文档中或在我读过的书(不记得源代码)中都回想起一个Python线程的示例,该示例执行的操作与您尝试执行的操作类似。 Something like this should work: 这样的事情应该起作用:

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

Why do you need Paramiko module or to create an input if python can do itself ? 如果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!')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM