前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >expect 实现脚本的自动交互

expect 实现脚本的自动交互

作者头像
嵌入式视觉
发布2022-09-05 14:15:19
9870
发布2022-09-05 14:15:19
举报
文章被收录于专栏:嵌入式视觉

Contents

expect 介绍

这篇文章大部分参考这里,expect 的用户网上靠谱的文章实在太少了,导致我没法同时学习多个文章好加以总结,毕竟一家之言还是有所偏驳。

expect 是建立在 tcl 语言基础上的一个自动化交互套件, 在一些需要交互输入指令的场景下, 可通过脚本设置自动进行交互通信。可以将交互过程如:ssh 登录、ftp 登录、scp 复制文件等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率。其交互流程是: spawn 启动指定进程 -> expect 获取指定关键字 -> send 想指定进程发送指定指令 -> 执行完成, 退出。

安装 expect

使用以下代码检测 expect 是否已经安装

代码语言:javascript
复制
 ls /usr/bin | grep expect 

如果显示为空,则使用以下命令安装

代码语言:javascript
复制
sudo apt-get install tcl tk expect

expect 命令学习

expect 是基于 tcl 演变而来的,所以很多语法和 tcl 类似,基本的语法如下所示:

代码语言:javascript
复制
# 首行加上 /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 工具,实际上学习三个核心指令 spawnexpectsend的使用,这三个指令的具体语法理解见下文。

spawn

代码语言:javascript
复制
spawn [args] program [args]

用以创建新的进程,并执行给定的程序,后面就可以使用 expect 监听 spawn 创建进程程序的输出。

expect

expect 常用语法(模式-动作)如下:

代码语言:javascript
复制
expect [[-opts] pattern body1] ... [-opts] pattern [bodyn]

expect 的参数是一连串的 opts,pattern,body,也就是 expect 可用来监听多个输出,pattern 就是用来匹配期望的输出,一旦匹配上就执行后面的 bodyopts 表示可选。用法示例如下:

代码语言:javascript
复制
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

代码语言:javascript
复制
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 的出现解决了这个问题,实例脚本如下。

代码语言:javascript
复制
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

代码语言:javascript
复制
# 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工具实现脚本的自动交互

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-09-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • expect 介绍
  • 安装 expect
  • expect 命令学习
    • spawn
      • expect
        • send
          • expect eof
          • expect 实例
            • 自动拷贝 scp
              • 自动登录 ssh
              • 参考资料
              相关产品与服务
              云服务器
              云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档