what
- expect工具是Linux下的一个自动化交互工具,与该工具交互的对象并不是用户,而是其它需要和用户交互的进程,其作用是替代用户和进程交互,以实现操作的自动化。
why
- 平时使用一些指令,如scp,ftp等,操作流程中需要手动输入一些参数,例如:passwd,账号等,如下:
xxx@xxx-Lenovo-V110-15IKB:~/notebook$ scp xxx@192.168.70.187:~/123 .
xxx@192.168.70.187's password:
- 因为命令使用中需要手动输入一些参数而不是以命令行参数的方式,不方便实现自动化操作,如需实现自动化操作,需要一些工具能替代用户,当进程需要手动输入时,自动输入一些参数,而expect 就是这样的工具。
how
- Linux下默认未安装该工具,需要手动安装,Ubuntu16.04上安装命令如下:
sudo apt install expect
* 安装会在/usr/bin/下生成expect工具。
spawn 启动新的进程
send 用于向进程发送字符串
expect 从进程接收字符串,获取匹配信息,匹配成功则执行expect后面的程序动作
interact 允许用户交互
exp_continue 在expect中多次匹配就需要用到
send_user 用来打印输出 相当于shell中的echo
exit 退出expect脚本
eof expect执行结束 退出
set 定义变量
puts 输出变量
set timeout 设置超时时间
1. spawn命令用来启动新的进程,spawn后的send和expect命令都是和使用spawn打开的进程进行交互。
2. send 命令接收一个字符串参数,并将该参数发送到进程。
3. expect命令和send命令相反,expect通常用来等待一个进程的反馈,我们根据进程的反馈,再发送对应的交互命令。
4. interact命令主要用于退出自动化,进入人工交互。比如我们使用spawn、send和expect命令完成了ftp登陆主机,执行下载文件任务,但是我们希望在文件下载结束以后,仍然可以停留在ftp命令行状态,以便手动的执行后续命令,此时使用interact命令就可以很好的完成这个任务。
* 简单流程
spawn启动指定进程-->expect,获取指定关键字-->send向指定程序发送指定字符-->执行完成退出.
* 复杂流程
1. 循环expect,send处理
2. 退出循环后interact手动处理
...
示例
由expect工具执行
* 文件: 1.sh
#!/usr/bin/expect
set timeout 30 #设置expect命令等待时长
set host "101.200.241.109"
set username "root"
set password "123456"
spawn ssh $username@$host
expect "*password*" {send "$password\r"}
interact
- 执行方式:expect 1.sh 或者 ./1.sh
- 获取命令行参数
#!/usr/bin/expect
if {$argc < 3} {
puts "Usage:cmd <host> <username> <password>"
exit 1
}
set timeout -1
set host [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
spawn ssh $username@$host
expect "*password*" {send "$password\r"}
interact
- argc表示参数个数,[lindex $argv x] 取参数值。
- expect - send(模式-动作)写法
1. expect "\*password*" {send "$password\r"}
2. expect {
"yes/no" { send "yes\n";exp_continue } #加上exp_continue程序不会退出该条expect
"password" { send "$password\n" }
}
* 由于脚本执行的性质,expect命令是顺序执行的,一条expect只会执行一次,即使用方式1的写法,如果执行完这条命令后,又出现password,不会触发send,方式2加上exp_continue才能实现循环触发。
通过shell调用
#!/bin/bash
passwd='123456'
/usr/bin/expect <<-EOF
set time 30
spawn ssh saneri@192.168.56.103 df -Th
expect {
"*yes/no" { send "yes\r"; exp_continue }
"*password:" { send "$passwd\r" }
}
expect eof
EOF