用expect(TCL)实现Linux下的交互

来源:互联网 发布:java awt swing 编辑:程序博客网 时间:2024/04/28 07:29

现代的Shell对程序提供了最小限度的控制(开始,停止,等等),而把交互的特性留给了用户。 这意味着有些程序,你不能非交互的运行,比如说passwd。 有一些程序可以非交互的运行,但在很大程度上丧失了灵活性,比如说su,ssh等。这表明Linux的工具构造逻辑开始出现问题。Expect恰恰填补了 其中的一些裂痕,解决了在Linux环境中长期存在着的一些问题。

Expect是基于TCL的,作为一个脚本语言,expect能在无需管理员参与的情况下实现自动交互(比如passwd,fsck,telnet等),expect也能用于自动测试一些应用程序。

expect的语法和shell的语法非常相似,它支持函数调用,有while语句,switch语句。

1) expect使用spawn调用其他的执行程序,比如

spawn telnet 218.199.20.98 2600

但是在使用的过程中发现spawn不支持管道和重定向,也就是说对于

ls |more ; mysql -p < update.sql 这样的命令spawn不能正确解析。

解决的办法是把这些命令放到一个shell脚本里面,在用spawn执行这个shell脚本。

2) expect 创建子函数使用proc标志,也即:

proc functionname { parameter1,parameter2 } {
......

}

调用子函数非常简单

functionname $param1 $param2

3) expect 使用expect ,send 组合实现自动交互 ,语法如下:

expect {
"login;" { send "$user\n" }
"passwd:" { send "$passwd\n" }

}
使用send的使用后面的内容不显示给用户,如要显示给用户,应使用send_user

4) 注意点:

1. expect里面基本是都是使用{} 而不是使用(),比如函数参数输入外面应用{},

应该是while { } 而不是 while ( ).

2. { 应和其他符合有空格, expect { 正确,expect{ 就会报错.

3. spawn 不支持管道和重定向.

5)一个例子:su的非交互

脚本文件:exp_su.sh

proc do_console_login {pass} {
set timeout 5
set done 1

while { $done } {
    expect {
        "Password:" {
        send "$pass\n"
        }
    eof {
        set done 0
      }
    }
  }
}

if {$argc<1} {

puts stderr "Usage: $argv0 password.\n "
exit 1
}

set PASS [lindex $argv 0]

spawn /tmp/ss
do_console_login $PASS

注意:/tmp/ss是重新写的一个脚本,因为spawn不能识别带参数的命令。其内容如下:

/bin/su - $user -c "/bin/ls /home/$user"

调用方法是: expect exp_su.sh 123456(即密码)

原创粉丝点击