千里江山图,自动化成诗:Expect脚本详解——从入门到进阶的自动化利器

目录

引言

Expect脚本基础

什么是Expect

基本语法

进阶应用

错误处理

正则表达式

并发处理

使用Shell脚本管理多个Expect脚本

在Expect脚本内部模拟并发

脚本复用与模块化

总结



引言

在自动化运维和测试领域,Expect脚本无疑是一把强大的利器。它以其灵活性和易用性,帮助开发者们实现了众多复杂的交互式任务自动化,如自动登录、自动化测试等。本文将带您从Expect脚本的基础入门,逐步深入到进阶应用,并通过丰富的案例和代码,帮助您快速掌握这一工具。

Expect脚本基础

什么是Expect

Expect是一个用于自动化交互式应用程序的脚本语言。它通过在脚本中模拟用户的输入和响应,来实现与命令行程序的自动化交互。Expect脚本通常与Tcl(Tool Command Language)一起使用,但也可以单独运行。其核心概念包括:

  • spawn:启动一个新的进程,如shell命令或脚本。
  • send:向进程发送输入。
  • expect:等待进程返回特定的输出。
  • interact:让用户和进程交互。

基本语法

一个基本的Expect脚本结构如下:

#!/usr/bin/expect  
# 设置超时时间  
set timeout 20  
# 启动新的进程  
spawn ssh user@hostname  
# 等待特定输出  
expect "password:"  
# 发送密码  
send "your_password\r"  
# 等待登录成功后的提示符  
expect "$ "  
# 执行命令  
send "ls -l\r"  
# 等待命令执行完毕  
expect "$ "  
# 退出会话  
send "exit\r"  
# 脚本结束  
expect eof

脚本解释

  1. #!/usr/bin/expect:指定脚本的解释器为Expect。
  2. set timeout 20:设置超时时间为20秒,如果20秒内未收到预期的输出,则脚本会报错并退出。
  3. spawn ssh user@hostname:启动一个新的ssh进程,尝试连接到指定的主机。
  4. expect "password:":等待进程输出“password:”提示。
  5. send "your_password\r":向进程发送密码,并回车。
  6. expect "$ ":等待登录成功后的shell提示符。
  7. send "ls -l\r":执行ls -l命令列出当前目录下的文件和目录。
  8. expect "$ ":再次等待命令执行完毕后的shell提示符。
  9. send "exit\r":发送exit命令退出ssh会话。
  10. expect eof:等待进程结束。

进阶应用

错误处理

在自动化脚本中,错误处理是非常重要的。Expect通过超时设置和条件语句来处理错误。

#!/usr/bin/expect  
set timeout 20  
spawn ssh user@hostname  
expect {  "password:" { send "your_password\r" }  timeout { puts "连接超时"; exit 1 }  eof { puts "连接失败或远程主机关闭"; exit 1 }  
}  
expect "$ "  
send "ls -l\r"  
expect "$ "  
send "exit\r"  
expect eof

在上述脚本中,我们使用了expect的条件语句来同时处理密码提示、超时和EOF(文件结束符)的情况。

正则表达式

Expect支持使用正则表达式来匹配复杂的输出,这使得脚本更加灵活和强大。

#!/usr/bin/expect  
spawn ssh user@hostname  
expect {  {.*[Pp]assword.*} {  puts "密码提示"  send "your_password\r"  }  timeout {  puts "超时"  exit 1  }  
}  
expect "$ "  
send "ls -l\r"  
expect "$ "  
send "exit\r"  
expect eof

在这个示例中,我们使用正则表达式{.*[Pp]assword.*}来匹配包含“password”或“Password”的任意输出。

并发处理

虽然Expect本身不支持多线程操作,但可以通过并发处理多个进程来模拟多线程效果。

#!/usr/bin/expect  
set timeout 20  
spawn ssh user1@hostname1 &  # 后台启动第一个SSH会话  
spawn ssh user2@hostname2 &  # 后台启动第二个SSH会话  expect {  "password:" {  send "user1_password\r"  exp_continue  }  eof {}  
}  expect {  "password:" {  send "user2_password\r"  exp_continue  }  eof {}  
}

在Expect脚本中实现真正的并发处理通常需要使用一些额外的工具或策略,因为Expect本身并不直接支持多线程或多进程并发。但是,我们可以通过循环、后台进程和wait命令来模拟并发行为。

不过,由于直接在Expect脚本中管理多个后台进程可能会变得复杂且难以维护,这里提供一个简化的思路,即使用shell脚本来管理多个Expect脚本的并发执行。

使用Shell脚本管理多个Expect脚本

你可以编写一个shell脚本来启动多个Expect脚本,每个脚本处理一个独立的任务。Shell脚本可以很容易地并行启动这些Expect脚本,并通过wait命令等待它们全部完成。

#!/bin/bash  # 启动第一个Expect脚本  
expect_script1.sh &  
pid1=$!  # 启动第二个Expect脚本  
expect_script2.sh &  
pid2=$!  # 等待两个脚本完成  
wait $pid1  
wait $pid2  echo "所有任务完成"

这里,expect_script1.sh和expect_script2.sh是两个包含Expect命令的脚本文件。每个脚本都在后台执行(通过在命令后添加&实现),并且shell脚本会捕获它们的进程ID(PID)以便稍后等待它们完成。

在Expect脚本内部模拟并发

如果你确实需要在单个Expect脚本中模拟并发(尽管这通常不是最佳实践),你可能需要利用Expect的exp_continue特性来在单个expect块中处理多个匹配项,但这实际上并不等同于真正的并发处理。

一个更实用的方法是,如果你需要处理多个会话或连接,你可以在一个Expect脚本中循环启动多个会话,并为每个会话使用不同的spawn和expect块。但是,这些会话仍然是顺序处理的,除非你将它们放入后台(在Expect中通常不推荐这样做,因为后台进程的控制会变得复杂)。

脚本复用与模块化

随着自动化任务的增加,脚本的复用和模块化变得尤为重要。你可以将常用的Expect代码片段封装成函数或过程,并在多个脚本中重用它们。

在Tcl(Expect的底层语言)中,你可以定义过程(procedures)来实现这一点。

#!/usr/bin/expect  # 定义登录过程  
proc login {user host password} {  spawn ssh $user@$host  expect {  "password:" {  send "$password\r"  exp_continue  }  timeout {  puts "登录超时"  exit 1  }  eof {  puts "登录失败"  exit 1  }  }  expect "$ "  
}  # 使用登录过程  
login user1 hostname1 password1  
send "ls -l\r"  
expect "$ "  
send "exit\r"  
expect eof  # 可以再次使用登录过程连接其他主机  
login user2 hostname2 password2  
# ... 执行其他命令

总结

Expect脚本是自动化交互式任务的强大工具,尤其适用于需要频繁输入用户名、密码或执行一系列命令的场景。通过掌握Expect的基本语法、进阶特性和错误处理机制,你可以编写出高效、可靠的自动化脚本,从而提高工作效率并减少人为错误。

此外,随着任务的复杂化,学会将脚本模块化、复用代码片段以及利用shell脚本管理多个Expect进程的能力,将使你能够更加灵活地应对各种自动化需求。希望本文能帮助你开启Expect脚本自动化的大门,并在自动化运维和测试的道路上越走越远。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/394998.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙Image组件设置长按手势回调事件

Image组件默认是可拖拽的,给Image组件设置draggable为false,即可成功触发长按事件:

基于Hadoop的北京市二手房价数据分析与可视化

文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主项目介绍总结每文 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主 项目介绍 随着中国经济的快速发展和城市化进程的加速,房地产市场已成为国民经…

难题:反转链表

定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。 思考题: 请同时实现迭代版本和递归版本。 数据范围 链表长度 [0,30]。 样例 输入:1->2->3->4->5->NULL输出:5->4->3->2->1->N…

sgetrf M N is 103040 时报错,这是个bug么 lapack and Openblas the same,修复备忘

1,现象 MN103040时,调用 sgetrf_ 时,无论是 LAPACK 还是 OpenBLAS,都出错: openblas: lapack: 2, 复现代码 出现问题的应该是由于M和N相对数字太大,乘积超出32bit整数的表达范围,…

vulnhub靶机tomato记录

https://www.vulnhub.com/entry/tomato-1,557/ 过程 用nmap对目标主机做全端口扫描,dirb做目录扫描,结果如下: 8888端口开放一个web服务,存在Basic认证,试了爆破无果,sun-answerbook是一个在线文档系统&am…

门店收银系统源码+同城即时零售多商户入驻商城源码

一、我们为什么要开发这个系统? 1. 商户经营现状 “腰尾部”商户,无小程序运营能力;自营私域商城流量渠道单一;无法和线下收银台打通,库存不同步,商品不同步,订单不同步; 2.平台服…

MongoDB学习记录

1、初识Mongo 概述:与关系型数据库不同,MongoDB 的数据以类似于 JSON 格式的二进制文档存储,通常称这种格式为Bson,Bson不仅支持JSON中已有的数据类型,还增加了一些额外的数据类型,例如日期和二进制数据&a…

python爬虫学习记录-请求模块urllib3

(文章内容仅作学习交流使用) urllib3是一个功能强大、条理清晰,用于HTTP客户端的第三方模块 urllib3-发送网络请求 使用urllib3发送网络请求时,需要先创建PoolManager对象,并使用该对象的request方法发送请求&#…

[Spring] Spring AOP

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…

Qt实现类似淘宝商品看板的界面,带有循环翻页以及点击某页跳转的功能

效果如下&#xff1a; #ifndef ModelDashboardGroup_h__ #define ModelDashboardGroup_h__#include <QGridLayout> #include <QLabel> #include <QPushButton> #include <QWidget>#include <QLabel> #include <QWidget> #include <QMou…

扩展【从0制作自己的ros导航小车】C++_ROS_QT5联合编译,简单界面为ROS开发增添交互

从0制作自己的ros导航小车 前言一、环境搭建二、联合编译三、测试 前言 前面已经实现了导航功能&#xff0c;对于之后的一些开发&#xff0c;有交互能力是比较重要的&#xff0c;比如小车上连接一块屏幕&#xff0c;通过屏幕来选择模式&#xff0c;可视化等等。QT是不错的选择…

LVS是什么?以及LVS-NAT以及DR模式实验

目录 NAT LVS LVS集群的类型&#xff1a; LVS-NAT模式实验 环境准备&#xff1a; 实验步骤&#xff1a; LVS-DR模式实验 题目&#xff1a; 环境准备&#xff1a; 实验步骤&#xff1a; LVS-防火墙标签解决轮询调度问题 环境准备&#xff1a; 实验步骤&#xff1…

智界S7 小鹏P7 G3 G3i P5 G9 P7i G6 X9维修手册和电路图线路图接线资料更新

汽修帮手资料库提供各大厂家车型维修手册、电路图、新车特征、车身钣金维修数据、全车拆装、扭力、发动机大修、发动机正时、保养、电路图、针脚定义、模块传感器、保险丝盒图解对照表位置等&#xff0c;并长期保持高频率资料更新&#xff01; 覆盖车型2020-2024年智界S7 小鹏…

在VScode中导入conda环境的记录【原创】

今天在vscode编辑器中运行一个python代码&#xff0c;发现终端可以运行&#xff0c;但是编辑器中点击Run会显示缺包&#xff0c;但是python包明明是有的&#xff0c;在自己的conda环境中。后来发现&#xff0c;是vscode没有发现我自己创建的conda环境&#xff0c;在vscode中导入…

51单片机个人学习笔记16(红外遥控)

前言 本篇文章属于STC89C52单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 [1-1] 课程简介_哔哩…

Java封装原生ES

文章目录 &#x1f31e; Sun Frame&#xff1a;SpringBoot 的轻量级开发框架&#xff08;个人开源项目推荐&#xff09;&#x1f31f; 亮点功能&#x1f4e6; spring cloud模块概览常用工具 &#x1f517; 更多信息1.spring-data-es操作ES1.引入依赖2.application.yml配置uris3…

高频焊接设备配电系统无源滤波系统的设计

1、高频焊机系统谐波状况简介 变压器容量&#xff1a;S11-M-1600/10KVA&#xff08;105%&#xff09;/0.4KV 短路阻抗&#xff1a;3.9% 谐波负载情况&#xff1a;一台600KW高频焊接设备 型号&#xff1a;GGP600-0.3-HC 输入电压&#xff1a;380V 输出电压&#xff1a;0…

【Python机器学习】回归——示例:预测乐高玩具套装的价格

用回归法预测乐高套装价格的基本步骤&#xff1a; 1、收集数据&#xff1a;用Google Shopping的API收集到的数据 2、准备数据&#xff1a;从返回的JSON数据中抽取价格 3、分析算法&#xff1a;可视化并观察数据 4、训练算法&#xff1a;构建不同的模型&#xff0c;采用逐步线性…

操作ArkTS页面跳转及路由相关心得

本文为JS老狗原创。 当前端不得不关注的点&#xff1a;路由&#xff0c;今天聊一聊鸿蒙相关的一点心得。 总体上套路不意外&#xff0c;基本就是&#xff08;尤其是Web&#xff09;前端那些事&#xff1a;维护路由表、跳转带参数、历史堆栈操作&#xff0c;等等。 历史原因&…

设计模式20-备忘录模式

设计模式20-备忘录 动机定义与结构定义结构 C代码推导优缺点应用场景总结备忘录模式和序列化备忘录模式1. **动机**2. **实现方式**3. **应用场景**4. **优点**5. **缺点** 序列化1. **动机**2. **实现方式**3. **应用场景**4. **优点**5. **缺点** 对比总结 动机 在软件构建过…