相关资料
维基百科:Expect
SourceForge:The Expect Home Page
TCL脚本言语简介
由于Expect是建立在TCL语言基础上的一个工具,因此首先检查一些TCL常见语法。
- 变量
在Expect中一般用于保存hostname/password/hostname
// 定义一个变量
set username "leo"
set hostname "xx.domain"
// 获取命令行参数(与bash不同的是第一个参数index为0)
set hostname [lindex $argv 0] //获取第一个参数,存入hostname变量中
set password [lindex $argv 1] //获取第二个参数,存入password变量中
- 数组
在Expect中一般用于保存服务器列表,显示并供用户选择
// 定义一个数组
set host_list(0) {host1 127.0.0.1}
set host_list(1) {host2 192.168.1.1}
set host_list(3) {host3 8.8.8.8}
//获取数组长度
set len [array size host_list]
- 获取用户输入
在Expect中一般接受用户输入选择,如密码、服务器等
system stty -echo //关闭终端回显,用于输入密码
send_user "please input password:" //发送给用户,提示输入密码
expect_user -re "(.*)
" //获取用户输入
set password $expect_out(1,string) //将用户输入用password变量保存
system stty echo //打开终端回显
- if条件分支
在Expect中用于逻辑判断
[string compare $host "123"] //判断变量是否相等,相等返回0,不相等返回1
set host [lindex $argv 0] //获取第一个参数
if ![string compare $host ""] { //此处花括号前必须有一个空格,具体请参考TCL语言规范
//如果host变量为空字符串
}
if {[string compare [string toupper $choose] "N"] == 0} {
//如果choose变量为"N"
} elseif {[scan $choose {%[0-9]} choose] == 0} {
//如果choose不是数字,scan用户匹配,详情参考TCL语法
} elseif { $choose < 0 || $choose >= $len } {
exit //退出
}
- for循环
在Expect可以用作显示数据
set len [array size host_list]
for {set index 0} {$index < $len} {incr index} {
puts "$index -> $host_list($index)"
}
// incr为自增关键字
// puts用于输出到用户,类似于send_user
Expect应用介绍
- ssh自动登录
set timeout 10 //设置timeout时间为10秒钟
spawn ssh $username@$hostname //执行ssh命令,登陆远程服务器
expect { //匹配服务返回信息
"yes/no" { send "yes
"; exp_continue } //第一次登陆服务器一般会提示保存公钥
"password" { send "$password
"; exp_continue } //提示输入密码
"$" { send "hostname
" } //终端下发送hostname
"Permission denied" { send_user "Permission denied (publickey,password)."; exit}
incorrect {puts "Invalid account or password!"; exit }
timeout { puts "Connection to $hostname timed out!"; exit }
eof { puts "Connection to $hostname failed: $expect_out(buffer)"; exit}
}
interact //登陆后的环境直接交给用户
// exp_continue可以解决为for/while循环的continue,Expect可以看做重新执行expect匹配
// exit是直接退出
- 接受窗口改变信号
如果使用expect登陆后,使用screen或者tmux,在用户终端大小调整情况下,因为窗口大小改变信号为同步到远程服务器会导致内容错乱。
trap {
set rows [stty rows]
set cols [stty columns]
stty rows $rows columns $cols < $spawn_out(slave,name)
} WINCH