2015-04-23 36 views
0

我寫了一個腳本,如果有足夠的可用空間,如果沒有足夠的可用空間,則將IOS文件發送到我的cisco設備,直到有文件爲止。除非IOS碰巧在一個目錄中,否則這一切都可以正常工作。Expect腳本幫助 - 從發送命令捕獲數據

僞代碼:

send directory command 
parse output and put it in format 
flash:c3560-ipservicesk9-mz.150-2.SE7.bin 
flash:/testfolder/c3560-ipservicesk9-mz.120-2.SE7.bin 

實際代碼:

set index 0 
send "dir /recursive \n" 
expect { 
     #this is the new code 
     -nocase -re "directory of (\[^\r\]+)" { 
       set test $expect_out(1,string) 
       exp_continue 
     } 
     #old code that just grabbed all ios, working 
     -nocase -re "(\[^\[:space:\]\]+.bin)" { 
       append test ":$expect_out(1,string)" 
       set ioses($index) $test 
       set index [expr $index + 1] 
       exp_continue 
     } 
     #final case which escapes the exp_continue, and sets the free space 
     -nocase -re "\\((.*) bytes free" {set free $expect_out(1,string)} 
} 

這裏是 「送DIR /遞歸」

Directory of flash:/* 

2 -rwx 17620224 Apr 20 2015 00:49:13 +00:00 c3560-ipservicesk9-mz.150-2.SE7.bin 
3 -rwx  2236 Mar 1 1993 00:01:02 +00:00 vlan.dat 
4 -rwx  4560 Apr 22 2015 14:30:05 +00:00 private-config.text 
7 -rwx  32329 Apr 17 2015 23:09:06 +00:00 backup_config 
6 -rwx  3096 Apr 22 2015 14:30:05 +00:00 multiple-fs 
8 -rwx  32344 Apr 22 2015 14:30:04 +00:00 config.text 

Directory of flash:/testfolder 

    9 -rwx  2236 Apr 23 2015 02:01:08 +00:00 c3560-ipservicesk9-mz.120-2.SE7.bin 

27998208 bytes total (10151936 bytes free) 

當我打印出來的輸出的例子我數組,我只有一個值flash:/testfolder/c3560-ipservicesk9-mz.120-2.SE7.bin「

我的算法顯然是錯的,怎麼去解析這個數據呢?

編輯 -

這是我最終的代碼,雖然DINESH的代碼工作以及

expect { 
     -nocase -re "directory of.+#" { 
       set input $expect_out(buffer) 
       set filesystem $input 
       set data [split $filesystem "\r"] 
       foreach dat $data { 
         if { [regexp -nocase {directory of} $dat] } { 
           regexp -nocase {directory of (.+)} $dat -> fs 
           regsub -all {/\*} $fs "" fs 
         } 
         if { [regexp -nocase {bin} $dat] } { 
           regexp -nocase { ([^[:space:]]+bin)} $dat -> f 
           if { [regexp {/} $fs] } { 
             lappend ioses $fs/$f 
           } else { 
             lappend ioses $fs$f 
           } 
         } 
         if { [regexp -nocase {bytes free} $dat] } { 
           regexp -nocase {\((.*) bytes free} $dat -> free 
         } 
       } 
     } 
} 
+0

你的腳本將首先設置'test'變量'閃光:/ *'然後將它與'附加c3560-ipservicesk9-mz.150-2 .SE7.bin'。最後變量'free'的值爲'10151936'。現在,你是否還需要與'testfolder'匹配? – Dinesh

+0

我可能應該在原始文章中提到它,但是我的數組的值原來只是「flash:/testfolder/c3560-ipservicesk9-mz.120-2.SE7.bin」和空索引 想要獲得我的目錄中所有.bin文件的列表,這樣我就可以刪除,直到有足夠的空間用於新的目錄 – genx1mx6

回答

1

既然你要匹配多個項目,這是更好地匹配所有內容,直到你得到命令dir /recursive的整個輸出。

send "dir /recursive\r" 
expect -re "(.*)<till your prompt>" 

這裏您提示可以$>#。一個一般性的方法可以像

set prompt "#|>|\\\$"; # Backslashes to match literal dollar sign 

一旦你從expect_out陣列的全部內容,應用regexp並獲得滿意的結果。

我只是假設輸入變量具有整個內容。爲了證明這一點,我將它分配給一個變量。

set input " 
Directory of flash:/* 

2 -rwx 17620224 Apr 20 2015 00:49:13 +00:00 c3560-ipservicesk9-mz.150-2.SE7.bin 
3 -rwx  2236 Mar 1 1993 00:01:02 +00:00 vlan.dat 
4 -rwx  4560 Apr 22 2015 14:30:05 +00:00 private-config.text 
7 -rwx  32329 Apr 17 2015 23:09:06 +00:00 backup_config 
6 -rwx  3096 Apr 22 2015 14:30:05 +00:00 multiple-fs 
8 -rwx  32344 Apr 22 2015 14:30:04 +00:00 config.text 

Directory of flash:/testfolder 

    9 -rwx  2236 Apr 23 2015 02:01:08 +00:00 c3560-ipservicesk9-mz.120-2.SE7.bin 

27998208 bytes total (10151936 bytes free) 

" 

# -all => To match all occurrence of the pattern in the given input 
# -line => To enable newline-sensitive matching. By default, newline is a 
# completely ordinary character with no special meaning. 
# -inline => To get the matched words as a list 
set dirnames [regexp -line -all -nocase -inline {directory of\s(\S+).*} $input] 
#puts $dirnames 
set filenames [regexp -line -all -inline {\S+\.bin} $input] 
#puts $filenames 
regexp {(\d+) bytes free} $input ignore freespace 

foreach {ignore actualdir} $dirnames filename $filenames { 
    //Checking if it contains '/*' or not. 
    if {[regsub {/\*} $actualdir {} actualdir]} { 
     lappend result $actualdir:$filename 
    } else { 
     lappend result "$actualdir/$filename" 
    } 
} 
foreach elem $result { 
    puts $elem 
} 
puts "Free space : $freespace" 

輸出:

flash:c3560-ipservicesk9-mz.150-2.SE7.bin 
flash:/testfolder/c3560-ipservicesk9-mz.120-2.SE7.bin 
Free space : 10151936 
+0

這幾乎就是我的目標。我來自更多perl的背景,並慢慢地學習expect/tcl的細節。 – genx1mx6

+0

你能解釋你的正則表達式標誌嗎?他們似乎都做同樣的事情。我還假設他們返回一個列表/數組? 我找不到關於您使用的「忽略」關鍵字的任何信息,它是如何工作的? 我編輯了我的原始文章,並附上我爲使其工作的代碼,您可以查看它並與您所做的相比較嗎?我認爲顯然我正在做更多的工作。 '捕捉\ r 分裂 迭代通過數組,直到我們得到預期值 ' – genx1mx6

+0

遺憾的第三點意見,但我只是意識到你的代碼假定「閃光」的時候,其實它的變量(可以的bootflash :, Disk0上:等) 'lappend result「flash:$ filename」' – genx1mx6