Expect 脚本帮助 - 从发送命令捕获数据
Expect script help - capturing data from send command
我写了一个脚本,如果有足够的可用空间 space,它会发送 IOS 文件到我的思科设备,如果没有足够的可用空间 space- 删除一个文件直到有是。除非 IOS 恰好在目录中,否则这一切都很好而且花花公子。
伪代码:
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)}
}
这里是 "send dir /recursive"
的输出示例
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
}
}
}
}
由于要匹配多个项目,所以最好匹配所有内容,直到得到命令的全部输出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
我写了一个脚本,如果有足够的可用空间 space,它会发送 IOS 文件到我的思科设备,如果没有足够的可用空间 space- 删除一个文件直到有是。除非 IOS 恰好在目录中,否则这一切都很好而且花花公子。
伪代码:
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)}
}
这里是 "send dir /recursive"
的输出示例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
}
}
}
}
由于要匹配多个项目,所以最好匹配所有内容,直到得到命令的全部输出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