expect自动化实战
expect命令是一个实现交互功能的软件套件,是基于TCL的脚本编程语言,在企业运维中,系统会以交互的形式要求运维人员输入指定的字符串,之后才能继续执行命令。例如:为用户设置密码时,一般情况下需要手工输入两次密码,比如使用ssh连接远程服务器时,第一次连和系统实现两次交互。
spawn启动指定进程>expect获取期待的关键字>send向指定进程发送字符>进程执行完毕,退出
expect 表达式 [动作]
例子:
[root@sf106232 scripts]# cat test.exp #!/usr/bin/expect spawn ssh root@10.19.106.61 uptime expect "*password:" {send "123456\n"} expect eof 结果: [root@sf106232 scripts]# expect test.exp spawn ssh root@10.19.106.61 uptime root@10.19.106.61's password: 16:55:15 up 236 days, 2:37, 1 user, load average: 0.12, 0.13, 0.09 交互式输入yes [root@sf106232 scripts]# cat uptime.exp #!/usr/bin/expect spawn ssh root@10.19.106.121 uptime expect { "yes/no" {exp_send "yes\r";exp_continue} ##匹配yes "*password" {exp_send "123456\r"} ##输入密码 } expect eof 注释:expect{},类似多行expect。 测试: [root@sf106232 scripts]# expect uptime.exp spawn ssh root@10.19.106.121 uptime The authenticity of host '10.19.106.121 (10.19.106.121)' can't be established. RSA key fingerprint is 67:10:80:cf:48:59:91:9f:33:08:40:34:7e:0f:d9:28. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '10.19.106.121' (RSA) to the list of known hosts. <h3>send_user命令</h3> 打印脚本信息,类似echo [root@sf106232 scripts]# cat test1.exp #!/usr/bin/expect send_user "iam suixiaofeng\n" send_user "i am a linuxer,\t" send_user "my blog is https://bk.devopstack.cn\n" [root@sf106232 scripts]# expect test1.exp iam suixiaofeng i am a linuxer, my blog is https://bk.devopstack.cn
exit命令
退出expect脚本,也可以做清理或提示工作
[root@sf106232 scripts]# cat test1.exp #!/usr/bin/expect send_user "iam suixiaofeng\n" send_user "i am a linuxer,\t" send_user "my blog is https://bk.devopstack.cn\n" exit -onexit { send_user "GOOD bye.\n" } [root@sf106232 scripts]# expect test1.exp iam suixiaofeng i am a linuxer, my blog is https://bk.devopstack.cn GOOD bye.
常用命令总结
spawn:用过spawn执行一个程序或命令,之后所有的expect操作都在这个执行的程序或命令中执行。
expect:获取spawn程序的交互信息,查看是否和其事先指定的信息想匹配。
send:当expect匹配了指定的字符串后,发送指定的字符串给系统,这些命令可以支持一些特殊的转义符号,例如: \r回车 \n换行 \t tab等
exp_contine:继续匹配expect程序或命令
send_user:打印脚本信息
exit:退出expect脚本,也可以做清理或提示工作
expect变量
set 变量名 变量值
[root@sf106232 scripts]# cat 20170718.exp #!/usr/bin/expect set test "suixiaofeng" puts $test send_user "$test\n" exit -onexit { send_user "hihi\n" } 测试: [root@sf106232 scripts]# expect 20170718.exp suixiaofeng suixiaofeng hihi
特殊参数变量
[root@sf106232 scripts]# vim 2017071801.exp [root@sf106232 scripts]# cat 2017071801.exp #!/usr/bin/expect #define var set file [lindex $argv 0] set host [lindex $argv 1] set dir [lindex $argv 2] send_user "$file\t$host\t$dir\n" puts "$file\t$host\t$dir\n" [root@sf106232 scripts]# expect 2017071801.exp blog.cool360.org 10.20.23.1 tmp blog.cool360.org 10.20.23.1 tmp blog.cool360.org 10.20.23.1 tmp 备注:传参 set 变量名 [lindex $argv 2] , $argc表示传参个数,$argv0 表示脚本的名字。 [root@sf106232 scripts]# cat 2017071801.exp #!/usr/bin/expect #define var set file [lindex $argv 0] set host [lindex $argv 1] set dir [lindex $argv 2] set name [lindex $argv0] puts $argc puts "$name\n" send_user "$file\t$host\t$dir\n" puts "$file\t$host\t$dir\n" [root@sf106232 scripts]# expect 2017071801.exp blog.cool360.org 10.20.23.1 tmp 3 2017071801.exp blog.cool360.org 10.20.23.1 tmp blog.cool360.org 10.20.23.1 tmp
expect中的if
if {条件表达式} {
指令
}
or
if {条件表达式} {
指令
} else {
指令
}
实例:
[root@sf106232 scripts]# cat 2017071802.exp #!/usr/bin/expect if { $argc !=3 } { send_user "Usge: expect $argv0 file host dir \n" exit } #define var set file [lindex $argv 0] set host [lindex $argv 1] set dir [lindex $argv 2] puts "$file\t$host\t$dir\n" [root@sf106232 scripts]# expect 2017071802.exp blog.cool360.org 127.0.0.1 /tmp blog.cool360.org 127.0.0.1 /tmp
eof关键字
结束匹配符
timeout
控制时间的变量
set timeout 30
expect timeout {puts "request timeout by linux"; return}
timeout
变量设置为0 表示立即超时, 为-1表示永不超时。
生产中自动化交互脚本
[root@sf106232 scripts]# cat 2017071803.exp #!/usr/bin/expect if { $argc != 2 } { puts "Usage: expect $argv0 ip commend" exit } #defind var set ip [lindex $argv 0] set cmd [lindex $argv 1] set password "123456" spawn ssh root@$ip $cmd expect { "yes/no" {send "yes\r"; exp_continue} "*password" {send "$password\r"} } expect eof
多台管理:
#!/bin/bash if [ $# -ne 1 ];then echo $"USAGE:$0 cmd" exit 1 fi cmd=$1 for n in 5 6 7 8 10 do expect zd.exp 10.19.106.$n "$cmd" done
免交互发送文件
#!/usr/bin/expect if { $argc != 3 } { puts "usage: expect $argv0 file host dir" exit } # set file [lindex $argv 0] set host [lindex $argv 1] set dir [lindex $argv 2] set password "123456" spawn scp -rp -P22 $file root@$host:$dir expect { "yes/no" {send "yes/r";exp_continue} "*password" {send "$password\r"} } expect eof
嗨、骚年、快来消灭0回复。