自动化运维的过程中,某些时候我们需要受用输入密码,这时候Expect这个工具可以完成。
首先要安装expect,直接yum安装就可以的。
下来我们试试expect这个工具:
使用ssh登陆:
#!/bin/expect #脚本解释器 spawn ssh root@192.168.116.137 uptime #开启expect自动交互,执行ssh命令 expect "*password" {send "123456\n"} #如果ssh命令输出匹配*password,就发送123456给系统 expect eof #表示交互结束
下来时匹配多个expect:
#!/bin/expect spawn ssh root@192.168.116.136 uptime expect { #将多个字符放在expect里面,然后spawn执行的过程中进行匹配 "yes/no" {exp_send "yes\r";exp_continue} #exp_send和前面的send一样,匹配多个字符串在每次匹配并执行动作后,加上exp_continue "*password" {exp_send "123456\n"} } expect eof
利用expect响应shell脚本中的多个read读入:
shell脚本: #!/bin/bash read -p "plz input your username:" name read -p "plz input your password:" pass echo -en "your username $name,your password $pass\n" ~ expect脚本: #!/bin/expect spawn sh /root/32.sh expect { "username" {exp_send "xpg\r";exp_continue} "password" {exp_send "123456\n"} } expect eof ~
18.4.5 send_user命令
相当于echo -n这个命令:
#!/bin/expect send_user "I AM OLDBOY\n" send_user "I am who?\n"
18.4.6 exit命令
类似shell中的shell,直接退出expect脚本,除了基本的退出脚本功能之外,还可以利用这个脚本做一些关闭前的清理和提示等工作:
#!/bin/expect send_user "I AM OLDBOY\n" send_user "I am who?\n" exit -onexit { send_user "Good bye\n" }
18.5 Expect程序变量
18.5.1普通变量
定义变量的基本语法如下:
set 变量名 变量值
打印:
puts $变量名
#!/bin/expect set password "123456" puts $password
18.5.2特殊参数变量
在expect里有与shell脚本里的$0,$1,$2等类似的特殊参数变量,用于接收及控制expect脚本传参。
在expect中$argv表示参数数组,可以使用[lindex $argv n]接收expect脚本传参,n从0开始,分别表示第一个[lindex $argv0] 参数、
例如:
#!/bin/expect set file [lindex $argv 0] set user [lindex $argv 1] set dir [lindex $argv 2] puts $argv0 puts $argc puts $file send_user "your name is $user;your dir is $dir\n"
18.6 Expect程序中的if条件语句
if { 表达式 } {
指令
}
或者
if { 条件表达式 } {
指令
}else {
指令
}
范例18-9 使用if语句判断脚本传参的个数,如果不符合给予提示:
#!/bin/expect if { $argc != 3 } { send_user "usage:expect $argv0 file host dir/n" exit -onexit { send_user "Good bye bye" } } set file [lindex $argv 0] set host [lindex $argv 1] set dir [lindex $argv 2] puts $file puts $argv0 puts $argc ~
18.7 timeout 关键字
这个关键字是服务于全局的,而不是某一个;和shell中的sleep很像,休息30s。
18.8企业生产场景下expect案例
开发expect自动交互的脚本:
#!/bin/expect if { $argc != 2 } { send_user "usage:expect $argv0 ip cmd/n" exit } set ip [lindex $argv 0] set cmd [lindex $argv 1] #set dir [lindex $argv 2] spawn ssh root@$ip $cmd expect { "yes/no" {exp_send "yes\r";exp_continue} "*password" {exp_send "123456\n"} } expect eof
上面是一个,我们向想办法批量执行execpt脚本试试:
用这个脚本调用上面的脚本,就可以实现循环批量
#!/bin/bash if [ $# - ne 1 ] then echo "USAGE:$0 cmd" exit fi cmd=$1 for i in 136 137 do expect /root/4.exp 192.168.116.$i $cmd done
18.8自动化 批量发送文件 **
下面这两个脚本相结合就能实现
#cat 5.exp #!/bin/expect if { $argc != 3 } { send_user "plz input:usage $argv0 ip cmd" exit } set file [lindex $argv 0] set ip [lindex $argv 1] set dir [lindex $argv 2] spawn scp -rp $file root@$ip:$dir expect { "yes/no" {exp_send "yes\r";exp_continue} "*password" {exp_send "123456\n"} } expect eof
#cat 55.sh #!/bin/bash if [ $# -ne 2 ]; then echo "plz input $0 file dir" exit fi file=$1 dir=$2 for i in 136 137 do expect 5.exp $file 192.168.116.$i $dir done ~