2012-10-29 6 views
3

안녕을 기대 사용하여 변수에 IP 주소를 추출, 나는 다음과 같은 사용하여 변수에 IP 주소를 가져 오기 위해 노력 해왔다 :내가 스크립트를 기대하는 새로운 오전 스크립트

set timeout -1 
spawn $env(SHELL) 
match_max 100000 
send "ifconfig | grep -A 1 'eth1' | tail -1\r " 
expect -re "inet addr:.* " {send "ping $expect_out(0,string)\r"} 
send -- "exit\r" 
expect eof 

문제는이 때문이다 일부 문자열 문자가있는 ifconfig 명령의 결과로 ping을 시도합니다.

누구든지 ifconfig 명령에서 IP 주소 만 추출하여 변수에 저장할 수 있습니까? 나는 $ expect_out (버퍼)도 사용하고 있었지만, 단지 내 머리를 감당할 수 없었다. 이 라인을 따라 어떤 도움을 많이 주시면 감사하겠습니다.

답변

0

'"ifconfig | grep -A 1 'en1' | tail -1\r"을 아래 라인과 같이 보냅니다.

regexp {inet.*?(\d+\.\d+\.\d+\.\d+)} $expect_out(buffer) match ip 

정규 표현식 명령은 괄호 '캡처 그룹의 IP 주소를 캡처 : 라인에서

expect -re "inet addr:.* " { 
    regexp {inet.*?(\d+\.\d+\.\d+\.\d+)} $expect_out(buffer) match ip 
    puts "Pinging $ip" 
    send "ping $ip\r" 
} 

:

send "ifconfig | grep -A 1 'en1' | tail -1 | cut -d' ' -f2\r"

1

당신은 당신의 기존 코드에 regexp를 사용할 수 있습니다 ':

(\d+\.\d+\.\d+\.\d+)

그런 다음 변수 ip에 저장하십시오.

expect_out(buffer) 변수는 지금까지로합니다 (expect -re 명령까지)을 기대 읽고 모든 것을 포함하는 소스 문자열이며, match는 말에 '(INET)'에서 전체 정규식 (모든 일치하는 문자열을 저장하는 또 다른 변수입니다 ip 주소). match은 캡처 그룹 이전에 변수가 있어야한다는 regexp 구문을 따르기 만하면됩니다.이 특정 예제에서는 쓰레기 데이터입니다. regexp의 수정 된 버전은이 예제에서 ip를 저장하기 위해 match를 사용할 수 있습니다 하지만 일반적으로 단일 문자열에서 여러 데이터 조각을 잡을 수 있으므로 캡처 그룹을보다 유연하게 찾을 수 있습니다.

Expect에서 상당히 광범위하게 사용하므로 regexp 명령과 regular expressions을 읽어 볼 수 있습니다.

+0

귀하의 회신에 감사드립니다. 그것은 완벽하게 작동합니다. 또한 기대 (버퍼) 및 IP 일치와 관련하여 어떤 마법이 진행되고 있는지에 대해 알려줄 수 있습니다. 일치가 예상되는 버퍼에서 ipaddress를 추출하는 방법은 무엇입니까? 그 위에 몇 줄을 떨어 뜨려주세요. 부탁해 줘서 고마워. – Mmudalagiri

+0

내 대답을 편집하여 세부 정보를 추가하십시오. –

+0

안녕하세요, 유익한 답변을 보내 주셔서 감사합니다. 여기에 문제가 하나 더있어. ipaddress의 마지막 자릿수가 잘리고 변수 "ip"에 저장됩니다. 예 : 올바른 것 대신 138.231.50.8 138.231.50.80 .. 어떤 아이디어가 ... ?? – Mmudalagiri

4

당신은 쉘 산란 할 필요가 없습니다 :

spawn ifconfig eth1 
expect -re {inet addr:(\S+)} 
set ipaddr $expect_out(1,string) 
expect eof 

spawn ping -c 10 $ipaddr 
expect eof 

것은 사실, 당신이 사용할 필요가 없습니다 기대 : 일반 티클에서 (추가 오류가 핑에 대한 검사와 함께) :

if {[regexp {inet addr:(\S+)} [exec ifconfig eth1] -> ipaddr]} { 
    set status [catch [list exec ping -c 10 $ipaddr] output] 
    if {$status == 0} { 
     puts "no errors from ping: $output" 
    } else { 
     puts "ERROR: $output" 
    } 
} 
+0

+1 나는이 접근법을 좋아합니다. 출력을 저장하기 위해 'catch'명령을 사용하여 exec를 사용하는 것과는 대조적으로 이런 방식으로 명령을 생성하는 데 어떤 이점이 있습니까? (예 : catch {exec ping 192.168.0.1} pingresults) –

+0

이것은 스폰 된 프로그램과 얼마만큼 상호 작용해야하는지에 따라 다릅니다. 실행이 필요하고 출력과 종료 상태를 캡처 한 다음'exec'을 사용하십시오. (적절한 exec 처리를 위해서는 [이 tcl wiki article] (http://wiki.tcl.tk/exec)를보십시오. 아래로 스크롤하여 "show discussion"을 클릭하십시오.) 스폰 된 프로그램이 프롬프트에 응답해야한다면 spawn을 사용하십시오/expect/send. –

+0

감사합니다. 링크를 확인하겠습니다. 상호 작용 각도가 당연한데 아마도 한 접근 방식이 다른 방식보다 '안전'하거나 '안전'한 것인지 궁금 할 수도 있습니다. –

0
$ifconfig 
eth0  Link encap:Ethernet HWaddr 00:1b:fc:72:84:12 
     inet addr:172.16.1.13 Bcast:172.16.1.255 Mask:255.255.255.0 
     inet6 addr: fe80::21b:fcff:fe72:8412/64 Scope:Link 
     UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 
     RX packets:638661 errors:0 dropped:20 overruns:0 frame:0 
     TX packets:93858 errors:0 dropped:0 overruns:0 carrier:2 
     collisions:0 txqueuelen:1000 
     RX bytes:101655955 (101.6 MB) TX bytes:42802760 (42.8 MB) 
     Memory:dffc0000-e0000000 

lo  Link encap:Local Loopback 
     inet addr:127.0.0.1 Mask:255.0.0.0 
     inet6 addr: ::1/128 Scope:Host 
     UP LOOPBACK RUNNING MTU:16436 Metric:1 
     RX packets:3796 errors:0 dropped:0 overruns:0 frame:0 
     TX packets:3796 errors:0 dropped:0 overruns:0 carrier:0 
     collisions:0 txqueuelen:0 
     RX bytes:517624 (517.6 KB) TX bytes:517624 (517.6 KB) 

이 시도 :

ifconfig | sed '2,2!d' | sed 's/.*addr://' | sed 's/\ .*//' > ipaddress 

이 의지 IP를주십시오

$vi ipaddress 
관련 문제