expect语法基础

http://zhumeng8337797.blog.163.com/blog/static/100768914201232023725334/

expect语法基础: while、for 循环、if 语句的用法示例  

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中的流程控制语句用法
2011-01-07 14:31
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] 
注意TCL会自动选择整数或者浮点计算: 
% set l [ expr $i /4.0] 
1.25 
% set l [ expr $i /4] 
在TCL里面可以使用+ - * /和%作为基本运算符,另外通常还包括一些数学函数,如a  
bs,sin,cos,exp和power(乘方)等等。 
另外,还有一个起运算符作用的命令incr,它用来对变量加一: 
% set i 1 
% incr i 
流程控制 
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; 
函数 
如同在一般的编程语言里面一样,在tcl里面也可以定义函数,这是通过proc命令实现  
的: 
proc my_proc {i}{ 
puts $i; 
这样就定义了一个名字叫proc的函数,它只是在终端显示输入变元的内容。 
要使用这个函数,简单地输入它的名字: 
% my_proc { 5 } 
如果变元的数目是0,只要使用空的变元列表,例如 proc my_proc {} {语句;}

 

你可能感兴趣的:(expect)