expect用法

巡山小妖精
569次浏览
2020年08月18日 05:37
最佳经验
本文由作者推荐

迎接挑战-冰心散文读后感


系统管理员在工作中经常会需要自动Telnet或者Ftp到指定的服务器上,成功login 之后自动执行一
些命令来完成所需的工作。
# ]2 Q1 K# m) w
当然,有很多编程语言可以去解决此类问题,比如用C、Perl、或者Expect。
4 H& ] C' W1 z9 A4 i' @% Y6 s
显然,尽管C是无所不能的,但是解决此类 问题还是比较困难,除非你熟悉Telnet或者Ftp协议;使
用Perl一样可以实现这样的功能,
Expect做的更出色,而且除支持UnixLinux平台外,它还支持Windows平台,它就 是为系统管理
和软件测试方面的自动交互类需求而产生的:
Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。
Expect语言是基于Tcl的, 作为一种脚本语言,Tcl具有简单的语法:
S) M% l2 t9 P ? v' u7 R- [
cmd arg arg arg
& W8 @% k7 h H# r2 R
一条Tcl命令由空格分割的单词组成. 其中, 第一个单词是命令名称, 其余的是命令参数 .
$$foo
$$符号代表变量的值. 在本例中, 变量名称是foo.
[cmd arg]
; E' 1 V' M2 l0 h: C8 l9 S
9 F! b% k' u8 g+ |' d
方括号执行了一个嵌套命令. 例如, 如果你想传递一个命令的结果作为另外一个命令的参数, 那么
你使用这个符号 .

双引号把词组标记为命令的一个参数. 符号和方括号在双引号内仍被解释 .
{some stuff}
% P2 j- O% t8 x' l Q
' t# w; B ^9 v+ x v
大括号也把词组标记为命令的一个参数. 但是, 其他符号在大括号内不被解释.
3 e1 h; k U# T


反斜线符号() 是用来引用特殊符号. 例如:n 代表换行. 反斜线符号也被用来关闭符号 , 引号,
方括号和大括号的特殊含义 .
. j5 H
8 n) o& u8 y3 C) f- e' r3 x
最好的学习方法就是边干 边学,对于已经熟悉一种编程语言的人来说,用另一种新的语言来写程序
解决问题,是很容易的事。
所以大概了解一下基本语法后,就一边动手解决问题,一边查手册吧。
关于Tcl和Expect的语法,请参考UnixLinux 平台任务的自动化相关部分。
+ X1 q; J$$ v) ]: E7 [
例1:下面是一 个telnet到指定的远程机器上自动执行命令的Expect脚本,该脚本运行时的输出如
下:2 O4 F& p) H1 H1 z F) n) H
) R$$ i2 _& h8 ~$$ @- V7 I! Q& t( f
# usrbinexpect sample_ root 111111
spawn telnet 10.13.32.30 7001
Trying 10.13.32.30...
Connected to 10.13.32.30.
Escape character is '^]'.
* c( c2 V7 Z0 R
l

* Q1 o8 Y8 I4 j2 ^+ A
accho console login: root
Password:
: H& Q2 aB5 X
Last login: Sat Nov 13 17:01:37 on console
$$ j# k6 p5 _. q x ?4 c& r
Sun Microsystems Inc. SunOS 5.9 May 2004
#
, y5 y9 `
; y( V& T, l: a# O8 J& i. K
Login Successfully...
7 ~! K
# uname -p
sparc
# ifconfig -a
lo0: flags=2001000849 mtu


8232 index 1
inet 127.0.0.1 netmask ff000000
eri0: flags=1000843 mtu 1500 index 2
z, I; h0 a9 t
7
inet 10.13.22.23 netmask ffffff00 broadcast 10.13.22.255
ether 0:3:ba:4e:4a:aa
# exit
& s% n' j7 p' V: p$$ V% F- y
( H+ C; D2 O8 I( L0 q9 b
accho console login:
4 O) p- W& L, P; {+ O* b a5 j
5 a# |7 P. k T- {& g1 C% A
Finished...
2 Q- Y
- t5 X0 `# U, j8 w$$ E2 j

下面是该脚本的源代码:
# vi sample_:
; R
proc do_console_login {login pass} {
set timeout 5
set done 1
& F4 S6 O3 d: E: F0 l&
, }& `* m+ G$$ L+ j
) H# `3 n, Q1 M8 N( M o- T
set timeout_case 0
3 k* B& n* ` U+ a0 Z; f
while ($$done) {
expect {
; v* O* q& . 6 C' @4 U' k



2 {4 J! A2 R; a- r2 x
* Z9 Z
. E {1 c! ?% m
set done 0
& j$$ }' ^+ X% ]% D3 X, U
send_user
}
2 TQ6 y, E. G
timeout {
- ]7 x; s* z) I ~! y ?
switch -- $$timeout_case {
0 { send


1 {
( X D) [) n9 [( Y2 a3 o+ @
send_user
send
}
. G |4 F, k7 a3 i n
s. [6 ]: |5 P: b
2 {
puts stderr
exit 1
}
}
2 T l( # A6 Z
) C8 |+ n% z* S& ? ~1 S
3 B9 k8 m
incr timeout_case
}
}
}
, k) p3 K, Y0 v9 N } L7 D
7 g: a4 m0 T8 L. S) B& [
}

proc do_exec_cmd {} {
6 {0 [% |( c9 a- x4 R) J4 W3 m
set timeout 5
send
7 ]3 b3 W2 d* Z
expect
send
expect
send
expect
& I4 c, R: ]0 C ! o
; w2 |5 q# W0 A4 W7 H, A& q
1 h9 ~% O; |- A: Q& F3 M& O
send
expect

send_user


}
7 v' }: b8 F' S' X7 Q) f, . j' l3 `
3 P h. M- K% d
if {$$argc<2} {

( i4 J) U# k, b( k* j5 q
puts stderr
exit 1
}
set LOGIN [lindex $$argv 0]
set PASS [lindex $$argv 1]
! f) b9 h: k; @: F
# R0 v, b
6 ]0 z x2 @5 g- B4 `
spawn telnet 10.13.32.30 7001
do_console_login $$LOGIN $$PASS
do_exec_cmd
close
% J# n! H
7 H6 S% k8 |8 C7 X$$ m- i8 k
0 G7 ~( s3 e3 }, ~9 y6 w
x- G3 e) d( f3 N% ]! P) {
exit 0
4 R4 ~+ S5 H+ @& u; o, ^ v$$ |
' E- Y! i+ w$$ H6 _

上面的脚本只是一个示例,实际工作中,只需要重新实现do_exec_cmd函数就可以解决类似问 题
了。
8 R
在例1中,还可以学习到以下Tcl的语法:
* j0 j# C7 A& j( `
; B( R; A8 z6 E6 a Z( m
1. 命令行参数
9 j9 B- [' g% w% ]
$$argc,$$argv 0,$$argv 1 ... $$argv n
if {$$argc<2} {
puts stderr
exit 1
}
8 A: N. ^% L1 k1 ^) F$$ k
- n& Q# ]2 p0 j% J' T
2. 输入输出
0 o9 3 C& ~& M0 C6 J


puts stderr
3. 嵌套命令
6 E- h3 q+ E& O& M( z
set LOGIN [lindex $$argv 0]
set PASS [lindex $$argv 1]
* {6 M+ g% ?# I
7 e$$ Q2 ?8 u7 ?- x( u
4. 命令调用
6 n7 u1 A0 X+ C# k3 b! r# ^
spawn telnet 10.13.32.30 7001
5. 函数定义和调用
& C% G6 v0 o% |* ?S3 [1 G6 L7 y- g
proc do_console_login {login pass} {
3 p b2 T$$ [3 e
..............
}
- O F! W: A: s5 k' m1 s1 d
6. 变量赋值
& p; m2 h6 M8 Y% p# ?1 Z
set done 1
( q- Q0 q* |# R4 g0 j* A& w
7. 循环
6 @$$ Q% d# }: b9 _ i
. ?9 e. b. C8 T$$ k j; g% Y0 @
while ($$done) {
................
3 o3 ^; @# E5
}
2 K* X9 i+ v& V
. X7 l& Q- f- l+ e; ~! R3 I- ]
8. 条件分支Switch
- P! m! @2 I2 N; s6 L) U: G
switch -- $$timeout_case {
0 {
...............
}
6 B C' s- ~) A
1 {
...............
1 Z0 K3 W4 J3 r


}
( 1 h: ?; O. l! G E. |
2 {
...............
}
}
U* u _+ M& b' X8 M
J% [( E t. @0 C
( B5 H+ d% N! t; t# e! v P
9. 运算
& h7 H2 P- i4 U6 x, E# k V
k! g$$ r4 _7 P
incr timeout_case
此外,还可以看到 Expect的以下命令:
send
expect
send_user
! P9 a8 D* j; c$$ a5 R E5 ~$$ N
Z4 ~ I, o. q6 @. k1 u
可以通过-d参数调试Expect脚本:
4 Q' t1 x( v; T& e! P3 v
# usrbinexpect -d sample_ root 111111
2 h8 [2 p9 n2 E' r( z
......调试输出和程序输出.......

西湖龙井茶的功效-试用期个人工作总结


初三毕业作文-小学毕业赠言


扳倒井-青岛农业大学分数线


丑小鸭续写-节操是什么


纪检监察工作要点-新年畅想作文


会议记要-格子铺


托福好还是雅思好-九年级思想品德


保密法学习心得-学生会工作总结