expect 实现脚本的自动交互
Contents
expect 介绍
这篇文章大部分参考这里,expect 的用户网上靠谱的文章实在太少了,导致我没法同时学习多个文章好加以总结,毕竟一家之言还是有所偏驳。
expect
是建立在 tcl
语言基础上的一个自动化交互套件, 在一些需要交互输入指令的场景下, 可通过脚本设置自动进行交互通信。可以将交互过程如:ssh
登录、ftp
登录、scp
复制文件等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率。其交互流程是:
spawn
启动指定进程 -> expect
获取指定关键字 -> send
想指定进程发送指定指令 -> 执行完成, 退出。
安装 expect
使用以下代码检测 expect
是否已经安装
ls /usr/bin | grep expect
如果显示为空,则使用以下命令安装
sudo apt-get install tcl tk expect
expect 命令学习
expect
是基于 tcl 演变而来的,所以很多语法和 tcl 类似,基本的语法如下所示:
# 首行加上 /usr/bin/expect
# spawn:后面加上需要执行的 shell 命令,比如说 spawn sudo touch testfile;
# expect:只有 spawn 执行的命令结果才会被 expect 捕捉到,因为 spawn 会启动一个进程,只有这个进程的相关信息才会被捕捉到,主要包括:标准输入的提示信息,eof 和 timeout。
# send 和 send_user:send 会将 expect 脚本中需要的信息发送给 spawn 启动的那个进程,而 send_user 只是回显用户发出的信息,类似于 shell 中的 echo 而已。
expect
实际的作用就是监听目标进程的输出(spawn
),根据期望输出(expect
),进行响应 (send
)。学习 expect
工具,实际上学习三个核心指令 spawn
、expect
、send
的使用,这三个指令的具体语法理解见下文。
spawn
spawn [args] program [args]
用以创建新的进程,并执行给定的程序,后面就可以使用 expect
监听 spawn
创建进程程序的输出。
expect
expect
常用语法(模式-动作
)如下:
expect [[-opts] pattern body1] ... [-opts] pattern [bodyn]
expect
的参数是一连串的 opts,pattern,body
,也就是 expect 可用来监听多个输出,pattern
就是用来匹配期望的输出,一旦匹配上就执行后面的 body
,opts
表示可选。用法示例如下:
expect {
busy {puts busy\n}
-re "failed|invalid password" {puts failed]\n} # -re选项表示开启正则匹配
timeout {puts timeout\n}
connected
}
注意,expect 会等待目标进程的输出,然后进行匹配,这个等待的时间默认是10秒,一旦超过这个时间就直接执行下一条指令,我们可以通过设置 timeout
来更改这个时间,set timeout 100
表示等待 100 秒。
send
send [-flags] string
将字符串传递给当前进程,这里就是模拟人的输入。
expect eof
expect eof
用以防止 spawn
进程程序执行完就直接退出的情况,有了它,程序会等待 spawn
进程程序结束再退出。由 spawn
启动的程序在结束的时候会产生一个 eof
标示,expect eof
会等待 spawn
进程程序的退出 eof
标示,一旦匹配到 eof
标识就什么也不做,什么也不做,没什么可做也就退出了。
但是,expect 是有默认超时时间的 -10
秒, 如果程序执行时间超过10 秒或更久,显然 expect eof 会超时,程序会直接退出,解决办法就是设置 timeout
。对于远程文件备份这种耗时比较长的操作,我们就需要设置 expect 的超时时间。
expect 实例
自动拷贝 scp
scp
远程复制文件(夹)涉及到很多交互式命令,我们不得不人工响应,expect
的出现解决了这个问题,实例脚本如下。
spawn scp -r $Dataset_path ftpdata@47.104.23.88:/mnt/data-4/ftpdata/honggao.zhang/
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$password\n" }
}
expect eof
此 Shell
脚本实现了 scp
复制本地目录到远程服务器,无需我们手动密码,同理 ssh
登录也可类似操作。建议把自动拷贝 scp
功能封装成函数形式,否则你得先 chmod a+x xxx.sh
然后 ./xxx.sh
才能执行脚本成功,下面的自动登录 ssh
实例代码就是封装成函数的形式。
自动登录 ssh
# ssh waibao server
# wait for upload success
echo "start ssh waibao server"
sshdzd(){
expect <<-EOF
set timeout 1000
spawn ssh $user_name@$server_ip
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$password\n" }
}
expect eof
EOF
}
sshdzd
脚本运行成功输出如下:
start ssh waibao server spawn ssh ftpdata@47.104.23.88 ftpdata@47.104.23.88’s password: Last login: Tue Jul 2 21:00:02 2019 from 221.226.80.68 Welcome to Alibaba Cloud Elastic Compute Service !
参考资料
expect自动交互详解 Ubuntu使用Spawn和expect实现ssh自动登陆 Linux中通过expect工具实现脚本的自动交互
相关文章
- 自动删除朋友圈的py脚本实现
- MongoDB运行日志实现自动分割的方法实例
- 脚本定时任务:Linux实现Cron自动启动脚本(linuxcron启动)
- 脚本Linux实现自动化执行PHP脚本(linux自动执行php)
- 构建Linux自动重启脚本 为你的系统实现更高的稳定性(linux自动重启脚本)
- Linux脚本实现自动运行神器(linux脚本自动运行)
- Linux脚本实现自动备份(linux备份脚本)
- Linux自动登录脚本实现更高效登录(linux登录脚本)
- 自动登录妙用Linux脚本:实现WWW账号自动登录(linuxwww用户)
- Linux 脚本实现快速自动部署(linux脚本自动部署)
- Linux自动备份文件脚本实现方案(linux备份文件脚本)
- Linux自动启动程序的实现(linux程序自动启动)
- Linux下自动化备份脚本的实现(linux自动备份脚本)
- Oracle 脚本导入:成功实现数据库自动导入(oracle脚本导入)
- 如何实现 Linux 自动运行脚本?(linux自动运行脚本)
- Oracle脚本备份技巧:轻松实现自动备份并保护数据(oracle脚本备份)
- 提升效率:Oracle自动排序法实现(oracle自动排序)
- Linux自动化:轻松实现脚本自启动(linux自动启动脚本)
- MSSQL脚本:自动执行实现节约时间(mssql脚本自动执行)
- 极速自动部署:Linux 脚本实现快捷上线(linux 自动部署脚本)
- Linux系统轻松实现自动配置IP(linux自动配置ip)
- 用Oracle实现自动物理表名转列名称(oracle 内容转列名)
- MySQL中如何实现自动累加ID(mysql中id如何累加)
- 无线搭建Redis集群极速轻松实现自动部署(离线搭建redis集群)
- 借助SH实现Redis缓存自动清理(sh清理redis脚本)
- 利用批处理文件和vbs脚本实现网站视频自动录制
- asp实现新评论自动发短信提示的代码
- jQuery.Autocomplete实现自动完成功能(详解)
- GridView自动增加序号(三种实现方式)
- PHP+jQuery实现自动补全功能源码
- 利用PHP+JS实现搜索自动提示(实例)
- thinkPHP实现表单自动验证
- Python实现的一个自动售饮料程序代码分享