在日常开发任务中,运行shell脚本有时候会提示输入密码的操作,如何让脚本自动输入密码呢?这时使用expect帮我们输入,Expect是基于Tcl发展而来的,它不仅可以进行交互,还可以根据程序的提示模拟标准输入,实现自动化交互执行的功能。
expect使用场景
文件传输
- 在
FTP/SFTP/SCP
文件传输过程中,如果服务要求输入用户名、密码或接受安全警告等交互操作,expect可以帮助自动完成这些步骤。
SSH登录自动化
- 当需要自动登录远程服务器并执行一系列命令时,expect可以模拟用户输入密码或通过密钥认证,并根据交互式提示继续执行。
sudo权限提升
- 当需要以root或其他用户权限运行命令,而系统配置为每次使用
sudo
都需要输入密码时,可以通过expect预先输入密码并执行后续命令。
数据库操作
- 在使用数据库管理系统(如
MySQL, PostgreSQL
等)的命令行客户端,在连接或执行敏感操作时需要输入密码验证,expect脚本能实现这一过程的自动化。
自动安装程序
- 在安装软件包或运行配置脚本的过程中,有些可能包含有交互式的问答环节,expect可用来自动回答这些问题,使得安装或配置过程完全自动化。
系统监控任务
- 在执行紧急维护或故障恢复时,可能涉及一系列复杂的手动交互流程,通过expect编写自动化脚本能够减少人为干预,提高效率和准确性。
网络设备管理
- 对于路由器、交换机和其他网络设备,很多管理界面都是基于文本协议(如telnet或SSH),expect可以用于自动登录设备并执行配置更改等任务。
总之,任何需要在命令行环境中进行人工交互的任务,只要可以预测到交互的内容,都可以尝试使用expect来实现自动化处理。
安装expect
查看是否安装了expect
whereis expect
如果出现如下提示,说明未安装
expect:[root@test ~]#
安装expect
yum install -y expect
安装成功提示
再次执行whereis expect
命令,如果出现如下提示,说明安装成功
expect: /usr/bin/expect /usr/share/man/man1/expect.1.gz
编写sudo提权脚本
以下是一个基本的expect
脚本示例,它会自动为sudo
命令提供密码。
脚本内容
#!/usr/bin/expect # 设置超时时间(单位秒) set timeout 10 # 设置你的密码变量 set password "your_password_here" # 执行sudo命令,并监视其输出 spawn su root # 当提示符出现时,发送密码 expect "*Password:" send "$passwordr" # 交互模式,等待命令执行完成 interact
脚本解释
-
spawn su root
是启动一个新的进程来运行su命令。 -
expect "*Password:"
等待包含”Password:”的提示符出现。 -
send "$passwordr"
发送密码变量值,并附带回车符以确认输入。 -
interact
可以用来继续监控和处理命令行中的其他交互。
常用命令说明
命令 |
说明 |
set timeout n |
设置expect语句超时时间为n秒。-1为永不超时 |
set name value |
设置变量名为name,其值为value |
set name [lindex $argv 0] |
设置变量名为name,其值为 传入 expect脚本的第一个 参数 。第一个参数的索引值为0,第二个为1,依次类推 |
spawn |
启动新的进程,执行命令或者指定程序 |
expect |
接收进程中返回的信息, 如果匹配成功(有大小写区分), 就执行expect后的动作 |
send |
向进程发送字符串 |
send_user |
用来打印信息,相当于shell中的echo |
exp_continue |
执行完expect后的动作后,使expect不退出,继续往下匹配 |
expect eof |
不允许用户交互,直接退出(这个用的会比interact多) |
interact |
允许用户交互 |
常见错误
spawn: command not found
执行编写好的expect脚本时,报以下错误信息,提示spawn: command not found
,但通过rpm -qa | grep expect
命令查看到expect软件包的确安装了,但是为什么仍然提示spawn命令找不到呢?
问题排查
重新排查了报错的脚本,发现脚本的首行是#!/bin/sh
,把他改成#!/usr/bin/expect
就可以了。
错误的脚本如下:
#!/bin/sh # 设置超时时间(单位秒) set timeout 10 # 设置你的密码变量 set password "your_password_here" # 执行sudo命令,并监视其输出 spawn su root # 当提示符出现时,发送密码 expect "*Password:" send "$passwordr" # 交互模式,等待命令执行完成 interact
问题分析
在编写expect脚本时,在文件的首行需要以#!/usr/bin/expect
作为shebang(即解释器指示符),目的是告诉操作系统应当使用expect解释器来执行该脚本内容。
然而,如果在执行该脚本时,误用了shell(如sh、bash等)命令进行解析和执行,由于shell并不具备解析和执行expect语句的能力,因此会导致脚本无法正确运行或出现错误。
所以,在排查expect脚本执行问题时,若确认脚本内部逻辑无误,但依然无法正常工作,应关注脚本是如何被调用和执行的。如果发现脚本是通过非预期的方式执行,那么这就可能是问题的根源所在。
总结
到此这篇关于Linux自动化交互脚本expect从安装到开发详解的文章就介绍到这了,更多相关Linux自动化交互脚本expect内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!