Shell编程基础(十一)使用 expect 脚本处理人机交互

使用 expect 脚本处理人机交互

安装expect

先检测是否有安装

bash 复制代码
yum list installex expect

或者 使用 rpm
rpm -q expect

如果没有安装,就先安装

bash 复制代码
yum install -y expect

适用场景

我们在执行某些程序时,可能会出现需要用户在过程中输入某些选项才能继续执行的场景。

比如

删除一个文件时,如果没有使用 -f 参数,系统会提示是否确认删除

bash 复制代码
rm tt.txt
rm: remove regular empty file 'tt.txt'?

rm tt.txt
rm: remove regular file 'tt.txt'?

又或者 ssh 远程连接服务器,也会有一些需要用户输入的东西

bash 复制代码
ssh root@192.168.0.104
The authenticity of host '192.168.0.104 (192.168.0.104)' can't be established.
ECDSA key fingerprint is SHA256:SK7IZ3gggoPEzJJXgp4RSQ8IFiPLOW/SMhwomRMR9kI.
ECDSA key fingerprint is MD5:d6:a5:d6:84:a3:f4:dd:ed:f5:ce:4a:67:c3:cd:cf:16.
Are you sure you want to continue connecting (yes/no)?

当我们确认连接后,又会弹出输入密码的提示

bash 复制代码
Warning: Permanently added '192.168.0.104' (ECDSA) to the list of known hosts.
root@192.168.0.104's password:

如果我们想要实现一些自动话的操作,是会被卡在这里的。

编写expect实现人机交互

基于上面两个场景,分别编写两个expect脚本处理

expect 大致的语法结构为

spawn 需人机交互的命令
expect 必须有空格 {

"交互提示语中的词,就模糊匹配,包含就行" {send "要输入的内容**\r**"} \r 或 \n 不可少,表示回车确认

}

执行完命令后。如果expect 执行环境开启了一个 的shell进程,则需要考虑执行完后对expect所在 shell进程的处理 interact (停留在所属shell进程中),expect_eof (退出所在shell进程)

如果只是在本机执行简单命令,则需要处理

自动确认删除文件

bash 复制代码
#!/usr/bin/expect
spawn rm tt.txt
expect {
  "rm: remove regular" {send "y\n"}
}
  1. 声明脚本解释器
  2. 使用 spawn 调起需要交互的程序
  3. 定义 匹配的提示信息以及对应的输入信,再通过 \r 或者 \n 确认

登录远程服务器自动确认并输入密码

bash 复制代码
#!/usr/bin/expect
spawn ssh root@192.168.0.104
expect {
 "yes/no" {send "yes\r";exp_continue}
 "password" {send "root\r"}
}
interact
  1. 声明 expect 脚本解释器
  2. 调起 需要交互的程序
  3. 匹配提示信息,并给定模拟输入的信息;exp_continue:如果匹配过了该项,在当前交互中还能继续匹配后面的交互信息
  4. interact,一旦ssh连接成功,此时的shell进程是远程机器上的进程;一般连接上机器后,还会做一些其他操作;因此这里使用 interact 保留当前会话,以便于执行后面的其他命令

在shell中执行 expect 脚本程序

expect 主要应用场景就是模拟用户与机器交互。一旦需要用户确认的交互完成后。通常还是会回到 shell 环境中进行其他工作。

因此,通常会将expect 脚本嵌入到 shell 脚本中,让expect做完自己那一部分工作就回到shell环境中。

我们可以直接在 shell脚本中直接编写expect 代码 或者 在shell 中调用expect脚本

  • 直接在shell中编写expect代码,**expect eof **
bash 复制代码
#!/bin/bash
echo "连接远程服务器..."
/usr/bin/expect <<-EOF
spawn ssh root@192.168.0.104
expect {
"yes/no" {send "yes\r";exp_continue}
"password" {send "root\r"}
}
# 在目标机器上查看ip
expect "#" {send "ip a\r"}
# 立即退出目标机器,如果没有这行,会等待默认超时时间10s,退出
expect "#" {send "exit\r"}

expect eof
EOF

以上脚本执行的功能是:

连接远程服务器-确认连接-输入密码-然后登录成功后的提示符是类似 [用户@host 当前目录]# 这样的提示 - 再进行匹配,然后执行 ip a 命令,查看目标机器id - 再匹配 # 退出远程连接,回到本地机器。

  • 在shell中调用expect脚本(通过 interact 和 expect eof 控制连接后,保持连接还是退出 而且这种有更好的维护体验,各管各嘛)
    expect.exp 脚本内容
bash 复制代码
#!/usr/bin/expect
spawn ssh root@192.168.0.104
expect {
 "yes/no" {send "yes\r";exp_continue}
 "password" {send "root\r"}
}

expect "#" {send "ip a\r"}

interact # 保持当前连接

调用 expect 的shell脚本

bash 复制代码
#!/bin/bash
/usr/bin/expect ./expect_login.exp

以上。

相关推荐
Dangks3 天前
[运维] 服务器本地网络可用性检查脚本
linux·运维·服务器·shell·network·系统工具
DreamADream4 天前
Shell编程中关于用户操作报错`用户无法登录`
shell
江上清风山间明月7 天前
shell脚本编写注意细节 ==、=等的区别
bash·shell·注意·相等·细节·==·=
188_djh12 天前
# linux从入门到精通-从基础学起,逐步提升,探索linux奥秘(十六)--shell
linux·运维·bash·shell·shell入门·shell变量·linux入门到精通
RamboPan12 天前
Mac 使用脚本批量导入 Apple 歌曲
macos·自动化·shell·apple·script
I'm Jie13 天前
一站式学习 Shell 脚本语法与编程技巧,踏出自动化的第一步
linux·ssh·shell·shell脚本·shell编程
rainsc15 天前
当多核变单核:破解CPU核心神秘失踪的终极指南!
服务器·shell
一丝晨光16 天前
编程语言支持中文变量吗?三字符组是什么来源?为什么结构体要考虑对齐?如何确定语言使用的地址是不是物理地址?用户态应用程序如何获取变量的物理地址?
java·linux·c++·c·shell·结构体·虚拟地址
188_djh16 天前
# linux从入门到精通-从基础学起,逐步提升,探索linux奥秘(十七)--shell运算符
linux·运维·bash·shell·shell脚本附带参数·shell运算符·shell文件测试运算符
咖啡调调。17 天前
⑤sed流编辑器与awk文本处理工具——项目实训任务
编辑器·shell·脚本