본문 바로가기

프로그래밍/Python

Programmability for Networker : Part 4

 


pingrange Python 예제로 살펴보는 포스팅의 3번째 편이자, 해당 예제의 마지막 편입니다.

물론 다음 편에서 다시 비슷하게 다뤄질 예정이긴 합니다.

 

기본 내용은 지난 포스팅과 이어지게 되며, 예제 소스는 이번 포스팅에도 동일하게 포함하여 보시기 쉽게 하였습니다.

 

혹시 기존 포스팅을 보지 못하신 분은 반드시!

 

Programmability for Networker : Part 2            Programmability for Networker : Part 3

 

을 보고 오셔야 합니다.

 

본 내용에 사용된 에제는 아래에서 볼 수 있습니다.

[ 예제 링크 ] https://github.com/datacenter/who-moved-my-cli

 

※ 본 내용의 진행은 Nexus 5548 6.0(2)N2(4) 기준입니다.

 

 


 

 

pingrange.py

import re

from cisco import cli

from argparse import ArgumentParser

def expandrange(rangefunc):

    hosts = []

    octets = rangefunc.split('.')

    for i,octet in enumerate(octets):

        if '-' in octet:

            octetrange = octet.split('-')

            for digit in range(int(octetrange[0]), int(octetrange[1])+1):

                ip = '.'.join(octets[:i] + [str(digit)] + octets[i+1:])

                hosts += expandrange(ip)

            break

    else:

        hosts.append(rangefunc)

    return hosts

 

parser = ArgumentParser('pingrange')

parser.add_argument('ip', help='IP range to ping, e.g., 10.1.0-1.0-255 will expand to 10.1.0.0/23')

parser.add_argument('options', nargs='*', help='Options to pass to ping', default=['count 1'])

args = parser.parse_args()

targets = expandrange(args.ip)

for ip in targets:

    tupleping  = cli('ping %s %s' % (ip, ' '.join(args.options)))

    strping = str(tupleping)

    m = re.search('([0-9\.]+)% packet loss',strping )

    print('%s - %s' % (ip, 'UP' if float(m.group(1)) == 0.0 else 'DOWN'))

 

 


 

 

[ 매개변수 ]

 

명령줄 매개변수

     •Python Script 실행 시에, 사용되는 매개변수는 sys.argv에 리스트 형태로 전달된다.

     리스트의 첫 번째 값은 해당 Script의 이름이고, 그 이후의 값이 실제 매개변수가 된다.

        따라서, sys.argv[1:] 으로 하면 실제 매개변수의 값만 리스트로 뽑을 수 있다.

     argparse 모듈을 사용 할 경우에는 매개변수에 대한 작업을 좀 더 편하게 할 수 있다.

 

argparse

     •class argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[],

                                           formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None,

                                           argument_default=None, conflict_handler='error', add_help=True)

     ArgumentParser 클래스는 실행 시의 매개변수에 대한 값을 손쉽게 처리하도록 매개변수의 값을 argparse 객체로 만들어 준다 .

     add_argument 메서드는 매개변수를 어떻게 분석하여 처리할지에 대한 부분 지정한다.

 

 

Args1.py : Code

import sys

argvList = sys.argv

for ar in argvList:

    print 'argv : %s' % ar

 

Args.py : 실행

>>> python  Args1.py 2014 ZIGI JaeSung

argv : I:/Network/Nexus/py/Args1.py

argv : 2014

argv : ZIGI

argv : JaeSung

 

Args2.py : Code

import argparse

parser = argparse.ArgumentParser('Args',description='Args Desc')

parser.add_argument('year', type = int)

parser.add_argument('nick', type = str)

parser.add_argument('name')                               # Type 미지정 시에는 Default로 Str Tytpe

args = parser.parse_args()

print "2014=%d , nick=%s , name=%s" % (args.year, args.nick, args.name)

 

Args.py : 실행

>>> python  Args.py 2014 ZIGI JaeSung

year=2014 , nick=ZIGI , name=JaeSung

 


 

 

[ 정규식 ]

 

❖ 정규식

     - 복잡한 문자열 패턴을 검색/추출/대치하는 규칙

 

re 모듈

     - Python에서 정규식을 사용하기 위해 제공하는 모듈

  

meta 문자

     - 문자나 문자 패턴을 반복의 표현을 나타나는 문자

 

     ▷ 메타 문자 [반복]

 

 Meta 문자

 내용

 예제

*

  문자를 0회 이상 반복

 Zi*Gi : ZGI, ZiGi, ZiiiiiiiiGi

+

 앞 문자를 1회 이상 반복

 Zi+Gi : ZiGi, ZiiiiiGi

?

 앞 문자를 0 or 1회 반복

 Zi?Gi : ZGi, ZiGi

{m}

 앞 문자를 m회 반복

 Zi{3} : Ziii

{m,n}

 앞 문자를 m~n 회까지 반복

 Zi{2,3} : Zii, Ziii

 

     ▷ 메타 문자 [매칭]

 

 Meta 문자

 내용

 예제

.

 개행문자를 제외한 모든 문자와 매칭

re.DOTALL 모드 시에는 개행문자 포함하여 매칭

 Z.Gi : ZiGi ZzGi, Z1Gi

^

1. 문자열의 시작과 매칭

   re.MULTILINE 모드에서는 각 줄의 시작과 매칭

2. 메타 문자 [ ]안에서는 해당 문자 예외

^ZiGi : ZiGi of Network (O) , Network ZiGi(X)

 

Z[^i]Gi : ZkGi, ZlGi (O) , ZiGi (X)

$

문자열의 마지막과 매칭

메타 문자 [ ] 내부에서는 순수한 $의 의미로 사용

$ZiGi : Network ZiGi (O), Network ZiGis (X

[ ]

 문자 집합 안에 속한 한 문자를 의미

‘-’로 범위지정 가능

 Z[hij]]Gi : ZhGi, ZiGi, ZjGi

 Z[a-z]Gi

|

 Or

 Zi|oGi : ZiGi, ZoGi

( )

정규식을 그룹으로 지정

정규식 내부에서 그룹을 만들고,

각 그룹을 Index에 따라서 가져올 수도 있다.

, Index를 벗어나게 될 경우에는 예외처리된다

 m = re.match('\s*([0-9]+) ([0-9]+)', ' 123 12')

print m.group(0)                 : ‘ 123 12’

print m.group(1)                 : ‘123’

print m.group(2)                 : ‘12’

 

 

      ▷ 메타 문자 [특수문자]

 

 Meta 문자

 내용

 예제

\\

‘\’ 자체를 문자로 인식

 Z.Gi : ZiGi ZzGi, Z1Gi

\d

 모든 숫자와 매칭

[0-9]

\D

 숫자가 아닌 모든 문자와 매칭

 [^0-9]

\s

공백이나 탭등의 문자와 매칭

[\t\n\r\f\v]

\S

공백이나 탭등이 아닌 문자와 매칭

[^ \t\n\r\f\v]

\w)

숫자 혹은 문자와 매칭

[a-zA-Z0-9]

 

 

match() vs search()

     •match

         - 문자열의 시작지점에서부터 일치하는지 확인

     •search

         - 문자열 내부에 부분적으로 일치하는 것이 존재하는지 확인

Ex)

     >>> re.match("c", "abcdef")  # No match

     >>> re.search("c", "abcdef") # Match

 

 


 

 이번 포스팅으로, git에 올라와 있는 Nexus pingrange 예제를 알아보기 위한 Python 내용을 살펴보았습니다.

각 항목별로 물론 더 많은 이론 내용이 있겠지만, 이번 포스팅의 중점은 코드를 이해하기 위한 기술 수준에서만 정리를 했습니다.

물론 조금 더 이해하기 쉽게(?)하기 위해 비교를 위해서 딱 코드에 있는 내용만 있지는 않고 +a의 내용이 있습니다.

각 코드별로 좀 더 이해를 돕기 위한 내용은 이번 pingrange에서는 하지 않았습니다.

물론 정리해놓은 기술 내용을 기반으로 보실 수 있기는 합니다만, 그래도 좀 더 각 줄 별로 주석을 달아드리겠지만

이번 코드가 아닌 다음 포스팅에서 다뤄질  pingrange의 변형 코드에서 할 예정입니다.

그 전까지는 코드를 먼저 나눠서 기술 내용을 바탕으로 이해해 보시면 좋을 듯 싶습니다.

 

아래는 pingrange를 이해하기 쉽게 하기 위한 각 실행 범위별 구간이니(Part 3에서 다뤄지기도 했습니다.),

참고하시면 좋을 것 같습니다.