liunx之expect操作详解
导航:
一、expect 安装、介绍、使用场景
二、expect 使用原理
三、expect 使用语法
四、expect 使用举例
五、expect 相关错误处理
- - - - - - - - - 分割线 - - - - - - - - - -
一、expect 安装介绍
1.expect 命令安装:
安装语句:yum install expect
2.expect 命令含义:
expect 是一种脚本语言,它能够代替人工实现与终端的交互,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信。
3.expect 使用场景:
(1)并根据预定标准回答其问题,回答“是”、“否”或将控制权交还给您
(2)远程连接设备并执行自动化操作
(3)主要是一些需要人机交互的地方,如果提前知道应该输入什么指令都可以使用 expect 工具
1. 原理介绍:
spawn
启动指定进程—expect
获取指定关键字—send
向指定程序发送指定字符—执行完成退出
2、spawn 命令介绍:
spawm 命令就是用来启动新的进程的。spawn 后的 send 和 expect 命令都是和 spawn 打开的进程进行交互的、
3、send 命令介绍:
send 命令接收一个字符串参数,并将该参数发送到进程,这个过程类似模拟人类输入密码
4、interact 命令介绍:
结合 spawn、expect、send 自动化的完成很多任务,interact 命令可以在适当的时候进行任务的干预,比如下载完 ftp 文件时,仍然可以停留在 ftp 命令行状态,以便手动的执行后续命令
1. expect 启用选项:
-c 执行脚本前先执行的命令,可多次使用
-d debug 模式,可以在运行时输出一些诊断信息,与在脚本开始处使用 exp_internal 1 相似。
-D 启用交换调式器, 可设一整数参数。
-f 从文件读取命令,仅用于使用 #! 时。如果文件名为 "-",则从 stdin 读取 (使用 "./-" 从文件名为 - 的文件读取)。
-i 交互式输入命令,使用 "exit" 或 "EOF" 退出输入状态
-- 标示选项结束 (如果你需要传递与 expect 选项相似的参数给脚本时),可放到 #! 行:#!/usr/bin/expect --
-v 显示 expect 版本信息
2.expect 命令参数:
spawn 交互程序开始,执行后面的命令或程序。需要进入到 expect 环境才可以执行,不能直接在 shell 环境下直接执行
set timeout n 设置超时时间,表示该脚本代码需在 n 秒钟内完成,如果超过,则退出。用来防止 ssh 远程主机网络不可达时卡住及在远程主机执行命令宕住。如果设置为 -1 表示不会超时
set 定义变量
$argv expect 脚本可以接受 bash 的外部传参,可以使用 [lindex $argv n]n 为 0 表示第一个传参,为 1 表示第二个传参,以此类推
expect 从交互程序进程中指定接收信息, 如果匹配成功, 就执行 send 的指令交互;否则等待 timeout 秒后自动退出 expect 语句
send 如果匹配到 expect 接受到的信息,就将 send 中的指令交互传递,执行交互动作。结尾处加上 \r 表示如果出现异常等待的状态可以进行核查
exp_continue 表示循环式匹配,通常匹配之后都会退出语句,但如果有 exp_continue 则可以不断循环匹配,输入多条命令,简化写法。
exit 退出 expect 脚本
expect eof spawn 进程结束后会向 expect 发送 eof,接收到 eof 代表该进程结束
interact 执行完代码后保持交互状态,将控制权交给用户。没有该命令执行完后自动退出而不是留在远程终端上
puts 输出变量
1.expect 脚本实现 ssh 自动登录远程服务器
#!/usr/bin/expect
spawn ssh mrswhite@192.168.37.9
expect "password:"
send "test20221007\r"
expect "#"
interact
expect expect_demo1.sh 执行查看运行结果:
2.expect 脚本实现 ssh 自动登录远程服务器(通用脚本,手动输入参数)
#!/usr/bin/expect
if {$argc < 3} {
puts "Usage:cmd <host> <username> <password>"
exit 1
}
set timeout -1
set host [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
spawn ssh $username@$host
expect "password"{send"$password\r"}
interact
./expect_demo2.sh 192.168.37.9 mrswhite test20221007 执行查看运行结果:
3. 在 shell 中嵌套 expect
通过 expect 嵌套 shell 使用语句在 shell 内直接执行,任何这样可以实现更多的功能
#!/bin/bash
user="mrswhite"
host="192.168.37.9"
password="test20221007"
/usr/bin/expect << EOF
set time 20
spawn ssh $user@$host
expect {
"*yes/no" {send "yes\r"; exp_continue}
"*password:" {send "$password\r"}
}
expect "*#"
send "pwd\r"
expect "*#"
send "df -h\r"
expect "*#"
send "exit\r"
interact
expect eof
EOF
1.invalid command name "/usr/bin/expect"
解决方案:此时是使用 bash 脚本嵌套了 expect 代码,所以执行采用以下两种方式都可以
./expect_demo3.sh
sh expect_demo3.sh
2.invalid command name ":" 转义问题
解决方案:send 里面的内容中的括号 [] 有问题,不能使用[], 将其去除或者添加转义字符
send "cat 20221007.txt | awk -F :'{print $2}'"
send "cat 20221007.txt | awk -F \[:\]'{print $2}'\r"