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

嚴華  论坛元老 | 2024-8-15 20:06:50 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1050|帖子 1050|积分 3150

目录
引言
Expect脚本底子
什么是Expect
基本语法
进阶应用
错误处置惩罚
正则表达式
并发处置惩罚
使用Shell脚本管理多个Expect脚本
在Expect脚本内部模仿并发
脚本复用与模块化
总结



引言


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

Expect脚本底子

什么是Expect

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


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

一个基本的Expect脚本布局如下:
  1. #!/usr/bin/expect  
  2. # 设置超时时间  
  3. set timeout 20  
  4. # 启动新的进程  
  5. spawn ssh user@hostname  
  6. # 等待特定输出  
  7. expect "password:"  
  8. # 发送密码  
  9. send "your_password\r"  
  10. # 等待登录成功后的提示符  
  11. expect "$ "  
  12. # 执行命令  
  13. send "ls -l\r"  
  14. # 等待命令执行完毕  
  15. expect "$ "  
  16. # 退出会话  
  17. send "exit\r"  
  18. # 脚本结束  
  19. expect eof
复制代码
脚本表明

  • #!/usr/bin/expect:指定脚本的表明器为Expect。
  • set timeout 20:设置超时时间为20秒,假如20秒内未收到预期的输出,则脚本会报错并退出。
  • spawn ssh user@hostname:启动一个新的ssh历程,实验毗连到指定的主机。
  • expect "password:":等待历程输出“password:”提示。
  • send "your_password\r":向历程发送密码,并回车。
  • expect "$ ":等待登录乐成后的shell提示符。
  • send "ls -l\r":执行ls -l命令列出当前目录下的文件和目录。
  • expect "$ ":再次等待命令执行完毕后的shell提示符。
  • send "exit\r":发送exit命令退出ssh会话。
  • expect eof:等待历程结束。
进阶应用

错误处置惩罚

在自动化脚本中,错误处置惩罚是非常紧张的。Expect通过超时设置和条件语句来处置惩罚错误。
  1. #!/usr/bin/expect  
  2. set timeout 20  
  3. spawn ssh user@hostname  
  4. expect {  
  5.     "password:" { send "your_password\r" }  
  6.     timeout { puts "连接超时"; exit 1 }  
  7.     eof { puts "连接失败或远程主机关闭"; exit 1 }  
  8. }  
  9. expect "$ "  
  10. send "ls -l\r"  
  11. expect "$ "  
  12. send "exit\r"  
  13. expect eof
复制代码
在上述脚本中,我们使用了expect的条件语句来同时处置惩罚密码提示、超时和EOF(文件结束符)的情况。
正则表达式

Expect支持使用正则表达式来匹配复杂的输出,这使得脚本更加机动和强大。
  1. #!/usr/bin/expect  
  2. spawn ssh user@hostname  
  3. expect {  
  4.     {.*[Pp]assword.*} {  
  5.         puts "密码提示"  
  6.         send "your_password\r"  
  7.     }  
  8.     timeout {  
  9.         puts "超时"  
  10.         exit 1  
  11.     }  
  12. }  
  13. expect "$ "  
  14. send "ls -l\r"  
  15. expect "$ "  
  16. send "exit\r"  
  17. expect eof
复制代码
在这个示例中,我们使用正则表达式{.*[Pp]assword.*}来匹配包罗“password”或“Password”的恣意输出。
并发处置惩罚

固然Expect本身不支持多线程操纵,但可以通过并发处置惩罚多个历程来模仿多线程结果。
  1. #!/usr/bin/expect  
  2. set timeout 20  
  3. spawn ssh user1@hostname1 &  # 后台启动第一个SSH会话  
  4. spawn ssh user2@hostname2 &  # 后台启动第二个SSH会话  
  5.   
  6. expect {  
  7.     "password:" {  
  8.         send "user1_password\r"  
  9.         exp_continue  
  10.     }  
  11.     eof {}  
  12. }  
  13.   
  14. expect {  
  15.     "password:" {  
  16.         send "user2_password\r"  
  17.         exp_continue  
  18.     }  
  19.     eof {}  
  20. }
复制代码
在Expect脚本中实现真正的并发处置惩罚通常必要使用一些额外的工具或战略,因为Expect本身并不直接支持多线程或多历程并发。但是,我们可以通过循环、背景历程和wait命令来模仿并发行为。
不过,由于直接在Expect脚本中管理多个背景历程大概会变得复杂且难以维护,这里提供一个简化的思路,即使用shell脚本来管理多个Expect脚本的并发执行。
使用Shell脚本管理多个Expect脚本

你可以编写一个shell脚本来启动多个Expect脚本,每个脚本处置惩罚一个独立的任务。Shell脚本可以很轻易地并行启动这些Expect脚本,并通过wait命令等待它们全部完成。
  1. #!/bin/bash  
  2.   
  3. # 启动第一个Expect脚本  
  4. expect_script1.sh &  
  5. pid1=$!  
  6.   
  7. # 启动第二个Expect脚本  
  8. expect_script2.sh &  
  9. pid2=$!  
  10.   
  11. # 等待两个脚本完成  
  12. wait $pid1  
  13. wait $pid2  
  14.   
  15. 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)来实现这一点。
  1. #!/usr/bin/expect  
  2.   
  3. # 定义登录过程  
  4. proc login {user host password} {  
  5.     spawn ssh $user@$host  
  6.     expect {  
  7.         "password:" {  
  8.             send "$password\r"  
  9.             exp_continue  
  10.         }  
  11.         timeout {  
  12.             puts "登录超时"  
  13.             exit 1  
  14.         }  
  15.         eof {  
  16.             puts "登录失败"  
  17.             exit 1  
  18.         }  
  19.     }  
  20.     expect "$ "  
  21. }  
  22.   
  23. # 使用登录过程  
  24. login user1 hostname1 password1  
  25. send "ls -l\r"  
  26. expect "$ "  
  27. send "exit\r"  
  28. expect eof  
  29.   
  30. # 可以再次使用登录过程连接其他主机  
  31. login user2 hostname2 password2  
  32. # ... 执行其他命令
复制代码
总结

Expect脚本是自动化交互式任务的强大工具,尤其实用于必要频仍输入用户名、密码或执行一系列命令的场景。通过把握Expect的基本语法、进阶特性和错误处置惩罚机制,你可以编写出高效、可靠的自动化脚本,从而提高工作效率并减少人为错误。
此外,随着任务的复杂化,学会将脚本模块化、复用代码片段以及利用shell脚本管理多个Expect历程的能力,将使你可以或许更加机动地应对各种自动化需求。希望本文能帮助你开启Expect脚本自动化的大门,并在自动化运维和测试的道路上越走越远。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表