使用 Expect 实现自动化交互操作
自动化处理交互式命令的利器:Expect
在 Linux 系统管理中,某些命令需要手动输入密码或确认信息,难以直接通过脚本自动完成。此时,Expect 提供了一个简洁高效的解决方案。它是一种基于 Tcl 的工具,专门用于模拟用户与交互式程序之间的对话,无需深入掌握 C 或 Perl 等复杂语言即可编写自动化脚本。
安装与调用方式
Expect 并非系统默认安装组件,可通过包管理器快速部署:
yum -y install expect
脚本中调用 Expect 支持两种常见模式:
- 独立脚本模式:将脚本首行指定为
#!/usr/bin/expect,使其可直接执行。 - 嵌入 Shell 脚本:在 Bash 脚本中使用 Here Document 方式调用,格式如下:
/usr/bin/expect << 'EOF'
# expect 命令块
EOF
核心语法与关键指令
以下是 Expect 脚本中最常用的命令及其作用说明:
变量定义(set)
使用 set 关键字声明变量:
set username "admin"
set timeout 60
其中 timeout 控制等待响应的最大时长(单位:秒),设为 -1 表示永不超时。
启动进程(spawn)
spawn 用于开启一个需要交互的子进程,例如 SSH 登录、FTP 连接等:
spawn ssh admin@192.168.10.5
该命令必须在 Expect 环境下运行,普通 shell 中无法识别。
匹配输出(expect)
expect 指令监听程序输出,并根据关键字做出响应。支持单条件和多分支写法:
expect "password:"
send "mypassword\r"
或多路匹配:
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "secret\r" }
timeout { puts "连接超时"; exit 1 }
}
使用 exp_continue 可在触发某条件后继续监听后续输出。
发送输入(send)
send 向目标程序发送字符串,通常以 \r 结尾表示回车确认:
send "ls -l /home\r"
保持交互(interact)
若希望脚本执行后将控制权交还给用户,可使用:
interact
否则脚本将在任务完成后自动退出。
参数传递
Expect 可接收外部传入的参数,使用 lindex $argv n 获取第 n 个参数(从 0 开始计数):
set host [lindex $argv 0]
set pwd [lindex $argv 1]
实战示例
示例一:Expect 脚本实现 SSH 自动登录
#!/usr/bin/expect
set host "192.168.1.6"
set user "root"
set pass "123456"
set timeout 30
spawn ssh $user@$host
expect "password:"
send "$pass\r"
expect "#"
send "echo 'Hello from remote' > /root/greeting.txt\r"
send "exit\r"
expect eof
运行后将在远程主机生成指定文件,全过程无需人工干预。
示例二:Shell 脚本中集成 Expect 实现自动化
#!/bin/bash
TARGET_IP="192.168.1.6"
USERNAME="root"
PASSWORD="123456"
/usr/bin/expect << EOF
set timeout 30
spawn ssh $USERNAME@$TARGET_IP
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "$PASSWORD\r" }
}
expect "#"
send "mkdir -p /root/testdir && touch /root/testdir/status.log\r"
send "exit\r"
expect eof
EOF
此方法便于在已有 Bash 脚本中灵活嵌入自动化交互逻辑。