http://zhumeng8337797.blog.163.com/blog/static/100768914201232023725334/
from CU
==两种for循环的写法
for {set i 0} {$i<=10} {incr i} {#i默认增量是1,即等价incr i 1。注意这个反括号一定要写在这行行末:args: should be "for start test next command"
............
.............}
Q:能不能改为i为我指定的几个数就好。比如我指定i为 3 5 6 7 9这几个数? 谢谢。
foreach i { 1 3 5 7 9 } {
puts "$i"
}
注:expect 用的是tcl语法,不是shell语法,或者用switch
==for/while循环写法
[15:33:05-Bob@hzling08:~/test/tcl]-(1109)No.108->$ cat tclfor.test
#!/usr/bin/expect --
# http://bbs.chinaunix.net/thread-2301733-1-1.html
# for Bob testing
#
puts "---1---"
for {set i 0} {$i < 10} {incr i} {
puts "I inside first loop: $i"
}
puts "---2---"
for {set i 3} {$i < 2} {incr i} {
puts "I inside second loop: $i"
}
puts "---3---"
puts "Start"
set i 0
while {$i < 10} {
puts "I inside third loop: $i"
incr i
puts "I after incr: $i"
}
set i 0
incr i
puts "---4---"
puts "$i"
# This is equivalent to:
set i [expr {$i + 1}] #expect里的加减法
puts "---5---"
puts "$i"
运行:
[15:33:09-Bob@hzling08:~/test/tcl]-(1110)No.109->$ ./tclfor.test
---1---
I inside first loop: 0
I inside first loop: 1
I inside first loop: 2
I inside first loop: 3
I inside first loop: 4
I inside first loop: 5
I inside first loop: 6
I inside first loop: 7
I inside first loop: 8
I inside first loop: 9
---2---
---3---
Start
I inside third loop: 0
I after incr: 1
I inside third loop: 1
I after incr: 2
I inside third loop: 2
I after incr: 3
I inside third loop: 3
I after incr: 4
I inside third loop: 4
I after incr: 5
I inside third loop: 5
I after incr: 6
I inside third loop: 6
I after incr: 7
I inside third loop: 7
I after incr: 8
I inside third loop: 8
I after incr: 9
I inside third loop: 9
I after incr: 10
---4---
1
---5---
2
===if的写法
if { $sync_flag == "true" } {
puts "Sync start at [clock format [clock seconds]]"
catch {eval exec ${TOOL_HOME}/bin/${sync_cmd} ${sync_parm} } output
puts $output
if { $output eq "SYNC complete!" } {
puts "SYNC complete!"
} else {
puts "SYNC error!"
exit 1
}
puts "Sync end at [clock format [clock seconds]]"
}
===ping的例子
set p_loop 5
while { $p_loop } {
send_user "\nStpe 1 Ping to server..."
set timeout 60
send "ping 10.1.1.1 -c5\r"
expect {
"64 bytes" {
send_user "ok"
set p_loop 0
}
timeout {
set p_loop [expr $p_loop-1] #expect里的加减法
send_user "failed.\n"
}
eof {
send_user "ping 10.1.1.1 -c5 FAIL\n"
exit 1
}
}
===expect读取文件的例子
#!/usr/bin/expect --
# http://scmbob.org/counting_file_lines.html
#open a file
set fd [open "/home/xiabao/myfile.txt" r]
set number 0
# read each line
while { [gets $fd line] >= 0 } { incr number }
puts "Number of lines: $number"
close $fd
==当前用户是root,我想用 su - oracle,然后在oracle下使用 expect -c 命令,不想用脚本,想用一行命令实现
su - oracle -c "expect -c 'spawn sqlplus / as sysdba; expect \"SQL>\"; send \"alter user sys identified by 123456
Expect语言是基于Tcl的, 作为一种脚本语言,Tcl具有简单的语法:
cmd arg arg arg
一条Tcl命令由空格分割的单词组成. 其中, 第一个单词是命令名称, 其余的是命令参数 . $foo $符号代表变量的值. 在本例中, 变量名称是foo. [cmd arg] 方括号执行了一个嵌套命令. 例如, 如果你想传递一个命令的结果作为另外一个命令的参数, 那么你使用这个符号 . "some stuff" 双引号把词组标记为命令的一个参数. "$"符号和方括号在双引号内仍被解释 . {some stuff} 大括号也把词组标记为命令的一个参数. 但是, 其他符号在大括号内不被解释. \ 反斜线符号(\) 是用来引用特殊符号. 例如:\n 代表换行. 反斜线符号也被用来关闭"$"符号 , 引号,方括号和大括号的特殊含义 . 1. 命令行参数 $argc,$argv 0,$argv 1 ... $argv n if {$argc<2} { puts stderr "Usage: $argv0 login passwaord.\n " exit 1 }
2. 输入输出
puts stderr "Usage: $argv0 login passwaord.\n "
3. 嵌套命令
set LOGIN [lindex $argv 0]
set PASS [lindex $argv 1]
4. 命令调用
spawn telnet 10.13.32.30 7001
5. 函数定义和调用
proc do_console_login {login pass} {
..............
}
6. 变量赋值
set done 1
7. 循环
while ($done) {
................
}
8. 条件分支Switch
switch -- $timeout_case {
0 { ............... } 1 { ............... } 2 { ............... } }
9. 运算
incr timeout_case
此外,还可以看到 Expect的以下命令: send expect send_user
expect eof
exit 上面两条语句可以判断spawn所运行的命令的退出,然后exit 还可以用interact可以进入所运行命令的交互界面。 expect使用spawn调用其他的执行程序,比如
spawn telnet 218.199.20.98 2600
但是在使用的过程中发现spawn不支持管道和重定向,也就是说对于
ls |more ; mysql -p < update.sql 这样的命令spawn不能正确解析。
解决的办法是把这些命令放到一个shell脚本里面,在用spawn执行这个shell
脚本。
expect 创建子函数使用proc标志,也即:
proc functionname { parameter1,parameter2 } {
......
}
调用子函数非常简单
functionname $param1 $param2
expect 使用expect ,send 组合实现自动交互 ,语法如下:
expect {
"login;" { send "$user\n" } "passwd:" { send "$passwd\n" }
}
使用send的使用后面的内容不显示给用户,如要显示给用户,应使用send_user
注意点:
1. expect里面基本是都是使用{} 而不是使用(),比如函数参数输入外面应用{},
应该是while { } 而不是 while ( ).
2. { 应和其他符合有空格, expect { 正确,expect{ 就会报错.
3. spawn 不支持管道和重定向.
TCL的运算方式比较别扭,它使用expr命令作为计算符号,其用法类似C语言的+=和/=
,例如,
% set j [expr $i/5]
1
注意TCL会自动选择整数或者浮点计算:
% set l [ expr $i /4.0]
1.25
% set l [ expr $i /4]
1
在TCL里面可以使用+ - * /和%作为基本运算符,另外通常还包括一些数学函数,如a
bs,sin,cos,exp和power(乘方)等等。
另外,还有一个起运算符作用的命令incr,它用来对变量加一:
% set i 1
1
% incr i
2
流程控制
tcl支持分支和循环。分支语句可以使用if和switch实现。if语句的和C语言类似,如
if { $ x < 0 } {
set y 10;
}
注意判断子句也需要使用花括号。
与C语言一样,tcl的if语句也可以使用else和elseif。
switch语句的用法有点类似这样:
switch $x {
0 { set y 10;}
10 { set y 100;}
20 { set y 400;}
}
与C的switch语句不同,每次只有符合分支值的子句才被执行。
循环命令主要由for,foreach和while构成,而且每一个都可以使用break和continue
子句。
for语句的格式有点类似这样:
for { set i 0} {$i < 10} { incr i} {puts $i}
将会输出从1到9的整数。
如果用while循环,这个句子可以写成
while {$i < 10 } {
puts $i;
incr i;
}
foreach是对于集合中的每一个元素执行一次命令,大致的命令格式是
foreach [变量] { 集合 } {
语句;
}
例如
% foreach j { 1 3 5} {
put $j;
}
1
3
5
函数
如同在一般的编程语言里面一样,在tcl里面也可以定义函数,这是通过proc命令实现
的:
proc my_proc {i}{
puts $i;
}
这样就定义了一个名字叫proc的函数,它只是在终端显示输入变元的内容。
要使用这个函数,简单地输入它的名字:
% my_proc { 5 }
5
如果变元的数目是0,只要使用空的变元列表,例如 proc my_proc {} {语句;}
|