2012-02-16 3 views
0

시스코 장비에 로그인하기 위해 작은 Expect 스크립트를 작성했습니다. 한 번 로그인하면 반복적으로 명령을 실행하고 grep 출력을 원합니다.Expect와 BASH 믹싱

#!/usr/bin/expect 

send_user "Device name: " 
expect_user -re "(.*)\n" 
set host $expect_out(1,string) 

send_user "Username: " 
expect_user -re "(.*)\n" 
set user $expect_out(1,string) 

stty -echo 
send_user -- "Password: " 
expect_user -re "(.*)\n" 
set pass $expect_out(1,string) 
stty echo 

send_user "show int " 
expect_user -re "(.*)\n" 
set intf $expect_out(1,string) 
send_user "\n" 

spawn telnet $host 
expect "Username:" 
send "$user\r" 
expect "Password:" 
send "$pass\r" 
expect ">" 

이 시점에서 우리는 "show int xxx"명령을 반복적으로 실행하고 특정 줄의 출력을 grep하려고합니다. grep이 Expect에 없으며 sleep과 같은 명령이 없으므로 show int 명령을 실행하여 특정 회선 밖으로 grepping 명령을 실행할 수 있습니다. Expect와 Bash를 어떻게 섞을 수 있습니까?

업데이트 : : 이제 스크립트를 거의 완료했습니다.이 마지막 장애물을 극복하고 나면 전체 스크립트를 게시합니다. 줄 set bytesnow [exec grep "packets input" \< showint | cut -d \ -f 9]이 오류를 던지고 있습니다.

child process exited abnormally 
    while executing 
"exec grep "packets input" < \showint | cut -d \ -f 9" 

하지만 테스트 스크립트에서 제대로 작동합니다. ./showint 파일이 있습니다. 명령 행에서이 명령을 실행해도 문제가 없습니다. 나는 틀린 것을 해결할 수 없다?

UPDATE : 더 조사 (http://wiki.tcl.tk/8489)에는 패턴 일치 명령을 넣어 찾을 수 없습니다 의미 상태 코드 1과 grep 종료가에서 잘 작동하는지 나에게 보여 주었다 커맨드 라인?/full/path/to/showint와 함께조차.

end : 나는 바보가 무엇인지 깨닫고 실수를 고쳤습니다. 모든 도움을 주셔서 감사합니다 : D는

+0

하! Typo, corrected, cheers;) – jwbensley

+0

글쎄, 라우터 9에서 # 9 필드를 찾고있는 것 같습니다. int | i 패킷 입력 '필드에 공백을 구분 기호로 사용합니다. 출력물에는 8 개의 필드 만 있습니다. 당신이 성취하고자하는 것을 우리에게 말할 수 있습니까? '798518177 패킷 입력, 60933723489 바이트, 0 버퍼 없음' – resmon6

+0

스위치/라우터의 출력 라인이 라인을 들여 쓰기 시작할 때 공백이 있기 때문에 "-f 9"를 사용했습니다. 나는 그 출력 라인의 바이트 값에 따라 나아가고있다. 바닥에있는 내 대답을보십시오. 고마워 :) – jwbensley

답변

0

이것은 첫 번째 Expect 스크립트로, 인터페이스의 실제 처리량 (거의 1 초!)을 제공합니다. 아래 예제는 "패킷 입력"을 포함하는 행에 대해 grep을 입력하기 때문에 인터페이스 입력 속도를 제공합니다. 이 인터페이스를 "패킷 출력"으로 변경하여 해당 인터페이스의 실시간 출력 속도를 얻으십시오. 이 처음 기대 스크립트로

#!/usr/bin/expect 

# Long delay for those tricky hostnames 

set timeout 60 

# Prompt user for device name/IP, username, password, 
# and interface to query (gi0/2) 

send_user "Device name: " 
expect_user -re "(.*)\n" 
set host $expect_out(1,string) 

send_user "Username: " 
expect_user -re "(.*)\n" 
set user $expect_out(1,string) 

stty -echo 
send_user "Password: " 
expect_user -re "(.*)\n" 
set pass $expect_out(1,string) 
send_user "\n" 
stty echo 

send_user "show int " 
expect_user -re "(.*)\n" 
set intf $expect_out(1,string) 
send_user "\n" 

spawn telnet $host 
expect "Username:" 
send "$user\r" 
expect "Password:" 
send "$pass\r" 
expect ">" 

set byteslast 0 
set bytesnow 0 

log_user 0 

# Enter a continuous loop grabbing the number of bytes that 
# have passed through an interface, each second. 
# The different in this number each cycle, is essentially 
# how much traffic this interface is pushing. 

while { true } { 
    send "show int $intf\r" 
    expect ">" 

    set showint [open "showint" "w"] 
    puts $showint $expect_out(buffer) 
    close $showint 

    set bytesnow [exec grep "packets input" \< showint | cut -d \ -f 9] 

    if { $bytesnow > $byteslast } { 
    set diff [expr $bytesnow - $byteslast] 
    set bps [exec expr "$diff" \* 8] 
    set kbps [exec expr "$bps" \/ 1000] 
    } elseif { $bytesnow < $byteslast } { 
    set diff [expr $byteslast - $bytesnow] 
    set bps [exec expr "$diff" \* 8] 
    set kbps [exec expr "$bps" \/ 1000] 
    } elseif { $bytesnow == $byteslast } { 
    set kbps 0 
    } 

    set byteslast $bytesnow 
    puts "$kbps Kbps\r" 

    sleep 1 
} 

, 나는 사람이 하나있는 포인터가 있으면 나는 모든 귀 해요 그래서이, (항상 그런 것은 내가 찾을 수 있음)보다 효율적이고 명확하게 작성 될 수 의심의 여지가 ! :)

exec grep 명령에 대한 내 문제는 그 전에 "showint"를 열어 본 파일이 닫히지 않았으며 다른 파일에 액세스하려고 시도한 것으로 밝혀졌습니다. 학교 소년 실수!

+1

TCL 명령 [regexp] (http://www.tcl.tk/man/tcl8.4/TclCmd/regexp.htm)을 사용하여 모든 것을 유지하고 싶다면 당신의 grep. 나는 당신의 명령이'[regexp {\ (\ d + \) bytes} $ showint bytesnow]'라고 믿습니다. 또한'[exec expr' 행은 내장 TCL'expr' 명령을 사용할 수있을 때'expr' 쉘 명령을 불필요하게 호출합니다. 그냥 명령에서'exec'을 제거하십시오. – resmon6

+0

또한 좀더 우아한 장기적인 해결책은 snmp를 사용하는 것입니다. [MRTG] (http://oss.oetiker.ch/mrtg/) 또는 [NMIS] (http://www.sins.com.au/nmis/)를 확인 했습니까? – resmon6

+0

전반적인 모니터링을 위해 SNMP가 있지만 문제 해결을 위해이 스크립트가 필요합니다. 폴러가 실행될 때 인터페이스 트래픽을 지금보고 싶을 때가 5 분이 아닙니다. :) – jwbensley

1

이것은 내가 당신에게 입력되는 패킷의 수를 얻을 수 있습니다

log_user 0 
while(1) { 
    send -- "sh int $intf | i packets input\r" 
    set timeout 5 
    expect { 
    -re "^ +(\d+) packets" { send_user -- "$expect_out(1,string)" } 
    timeout { send_user "broke?\n" } 
    } 
} 

그렇게 할 것 인 것이다.

+0

그건 내가 좋아하는 정말 멋진 생각인데, 내 스크립트의 목적 (내가 이전에 설명하지 않았으니 내 잘못이야)은 인터페이스의 현재 처리량을 얻는 것이다. 전체 스크립트는 내 대답을 참조하십시오.그래도 좋은 아이디어를 가져 주셔서 감사합니다 : D – jwbensley