expect脚本的基本语法就不多做介绍了,其它网上的文章很详细;这里只介绍下expect脚本中如何定义及使用函数,直接用例子说明吧,比较直观一些。
1.单参数函数
#!/usr/bin/expect -f
proc myfunc { TOTAL } {
set TOTAL [expr $TOTAL + 1]
return "$TOTAL"
}
set NUM 0
while {$NUM <= 5} {
puts "\nNumber $NUM"
set NUM [myfunc $NUM]
}
puts ""
expect脚本中函数定义是以关键字proc定义的,如上定义了一个函数myfunc用于执行+1操作(函数内部取参数的值可以用$符号,函数返回值也可直接用$取值返回),该函数打印5次变量++;
2.多参数函数
#!/usr/bin/expect -f
proc myfunc { tota totb } {
set TOTAL [expr $tota + $totb]
return "$TOTAL"
}
set NUM0 1
set NUM1 1
while {$NUM1 <= 15} {
puts "\nNumber $NUM0"
puts "\nNumber $NUM1"
set NUM0 [myfunc $NUM0 $NUM1]
set NUM1 [myfunc $NUM0 $NUM1]
}
puts ""
再来看一个包含两个参数的函数定义,如上参数以空格区分,myfunc返回两个参数的和,在函数调用时以“函数名 参数1 参数2”方式调用,设置返回值变量时则“ set 变量 [函数名 参数1 参数2] ”,上图显示一个Fabnaqi数列的打印。
3.实际项目中函数使用
#!/usr/bin/expect
puts "==================================================="
puts "calcaulate down_time in ms:"
puts "==================================================="
set timeout 10
proc caldelta { start end } {
set DELTA [expr $end - $start]
return "$DELTA"
# set start_s [ exec sh -c {echo $start | cut -d '.' -f 1 }]
# set start_ns [ exec sh -c {echo $start | cut -d '.' -f 2 }]
#
# set end_s [ exec sh -c {echo $end | cut -d '.' -f 1 }]
# set end_ns [ exec sh -c {echo $end | cut -d '.' -f 2 }]
#
# set time_ms [ exec sh -c { ($end_s-$start_s)*1000 + ($end_ns/1000000 - $start_ns/1000000) } ]
#
# puts ">>>>>>>deltaTime = $time_ms ms"
}
#proc getDeltaTiming {} {
#
# set Hunk=Hunk+1
# puts "-----Hunk:$Hunk-----"
#
# set start [lindex $argv 1]
# set end [lindex $argv 2]
#
# puts "start: $start"
# puts "end: $end"
#
# puts ">>>>>>>deltaTime = $start - $end ms"
# puts "---end---"
# send_user ""
#}
#新建虚机启动任务
spawn /usr/libexec/qemu-kvm -m 4G -smp 4 -name bcl-qemu --enable-kvm -boot cd -machine memfd-alloc=on -hda /root/linux.qcow2 -vnc :1 -monitor stdio
#等待虚机启动,#同时要在Host上Windows2窗口update qemu
sleep 50
expect {
qemu) {send "info status\r"}
}
expect {
qemu) {send "info version\r"}
}
#热升级开始,记录start时间
set begin_time [exec sh -c {(date +%s.%N)}]
expect {
qemu) {send "cpr-save /tmp/qemu.sav restart\r"}
}
expect {
qemu) {send "cpr-exec /usr/libexec/qemu-kvm -S -m 4G -smp 4 -name bcl-qemu --enable-kvm -boot cd -machine memfd-alloc=on -hda /root/linux.qcow2 -vnc :1 -monitor stdio\r"}
}
expect {
qemu) {send "info status\r"}
}
expect {
qemu) {send "cpr-load /tmp/qemu.sav\r"}
}
expect {
qemu) {send "info status\r"}
}
#热升级结束,记录end时间
set end_time [exec sh -c {(date +%s.%N)}]
expect {
qemu) {send "info version\r"}
}
#有时需要交互手动输入命令,比如guest在某进程时被打断然后liveupdate,看liveupdate后进程是否恢复
#interact
expect {
qemu) {send "q\r"}
}
#此命令用于等待timeout结束,用于防止puts命令抢先qemu)
expect eof
puts "start: $begin_time"
puts "end : $end_time"
set DOWNTIME [caldelta $begin_time $end_time]
puts "\ndown_time = $DOWNTIME s\n"
该脚本用于记录一次程序升级所占用的时间大小,时间计算主要利用嵌入的shell脚本date命令。