1 expect简介
expect是一个基于Tcl脚本语言的工具,专门用于自动化交互式应用程序的命令行工具,通常用于处理需要用户输入的场景,能够模拟用户输入,自动响应程序的提示,从而实现无需人工干预的自动化操作。通过编写expect脚本,可以模拟用户输入,实现自动化操作。
expect 的核心功能包括:
- 启动进程:通过spawn启动一个交互式程序
- 等待输出:通过expect等待程序的特定输出
- 发送输入:通过send向程序发送输入
- 交互模式:通过interact将控制权交还给用户
2 expect安装
yum install expect -y查看安装版本:
[root@node1 ~]# expect -v
expect version 5.45
[root@node1 ~]#
3 expect基本语法
expect脚本通常以#!/usr/bin/expect开头,基本语法:#!/usr/bin/expectspawn <command> #启动一个进程
expect "<pattern>" #等待特定输出
send "<response>\n" #发送输入
示例:实现SSH自动化登录
vim ssh.sh #编辑文件添加如下内容
#!/usr/bin/expect# 设置超时时间
set timeout 30# 获取参数
set user [lindex $argv 0]
set host [lindex $argv 1]
set password [lindex $argv 2]
set command [lindex $argv 3]# 启动 SSH 连接
spawn ssh $user@$host# 处理密码提示
expect "password:"
send "$password\r"# 处理登录后的提示符
expect "*$user*"
send "$command\r"# 保持交互
interact
使用方法:
执行脚本时,传入用户名、主机、密码和操作的命令作为参数
./ssh.sh root 192.168.10.32 lahmy1c@ "cd tool|ls"[root@node1 ~]# ./ssh.sh root 192.168.10.32 lahmy1c@ "cd tool|ls"
spawn ssh root@192.168.10.32
root@192.168.10.32's password:
Last login: Tue Mar 11 11:53:47 2025 from node1
[root@node3 ~]# cd tool|ls
1.txt 2.txt 3.txt anaconda-ks.cfg Desktop Documents Downloads initial-setup-ks.cfg Music Pictures Public Templates tool Videos
[root@node3 ~]#
4 expect核心命令
4.1 spawn
作用:启动一个新的进程
示例:
spawn ssh user@hostname
4.2 expect
作用:等待程序的特定输出,可以匹配字符串或正则表达式
示例: expect "Password:"
4.3 send
作用:向程序发送输入
示例:
send "userpasswd\n"
4.4 set
作用:设置变量
示例:set user "username"
set pass "passwd"
4.5 interact
作用:将控制权交还给用户,允许手动交互
示例:
interact
4.6 exp_continue
作用:继续匹配下一个模式,通常用于处理多个可能的输出
示例:
expect {"password:" { send "passwd\n" }"yes/no" { send "yes\n"; exp_continue }
}
4.7 eof
作用:匹配输入流的结束
示例:
expect {"some_pattern" { send "response\r" }eof { exit }
}
4.8 puts
作用:输出变量或字符串到标准输出
示例:
set message "Hello, World!"
puts $message
5 场景分享
批量批量修改用户密码案例:
1.主脚本程序:创建main_exec.sh文件并添加如下内容
#!/bin/bash# Enable environment configuration
source /etc/profile# Define basic paths
home_dir=/root/monitor
shell_home=${home_dir}/shell
log_home=${home_dir}/log
conf_home=${home_dir}/config
ssh_ip_conf=${conf_home}/ip_list.cfg
log_file=${log_home}/mod_user_passwd.log# General user information
user_name=lianggj
passwd=lahmy1c@
mod_time=$(date "+%y%m%d" -d "-0day")
new_passwd=lahm@${mod_time}!# Password validation regex
param_input_rule='/^(?![A-z0-9]+$)(?![A-z~@*()_]+$)(?![0-9~@*()_]+$)([A-z0-9~@*()_]{10,})$/'# Function to validate password input
validate_password() {if [[ ! ${root_passwd} =~ ${param_input_rule} ]]; thenecho "Error: Password does not meet complexity requirements."exit 1fi
}# Function to handle user input
input_params() {read -p 'Please enter root password (or "Q" to quit): ' root_passwdif [[ ${root_passwd} == "Q" || ${root_passwd} == "q" || -z ${root_passwd} ]]; thenecho "You entered nothing or chose to quit. Exiting!"exit 1fi# validate_password
}# Function to modify user password
mod_user_passwd() {if [[ ! -f ${ssh_ip_conf} ]]; thenecho "Error: SSH login configuration file not found: ${ssh_ip_conf}"exit 1fiwhile read -r ssh_ip; doecho "Processing IP: ${ssh_ip} for user: ${user_name}"/usr/bin/expect ${shell_home}/mod_user_passwd.sh ${ssh_ip} ${user_name} ${passwd} ${root_passwd} ${new_passwd} >> "${log_file}" 2>&1if [[ $? -ne 0 ]]; thenecho "Error: Failed to modify user on ${ssh_ip}. Check logs: ${log_file}"elseecho "Success: User modified on ${ssh_ip}."fidone < "${ssh_ip_conf}"
}# Main entrance
main() {echo "Starting script..."input_paramsmod_user_passwdecho "Script execution completed. Logs available at: ${log_file}"
}# Execute main function
main
2.修改密码脚本程序:创建mod_user_passwd.sh文件并添加如下内容
set ssh_ip [lindex $argv 0]
set user_name [lindex $argv 1]
set old_passwd [lindex $argv 2]
set root_passwd [lindex $argv 3]
set new_passwd [lindex $argv 4]#/usr/bin/expect
spawn ssh ${user_name}@${ssh_ip}
expect {"yes/no" { send "yes\r"; exp_continue}"*password:" { send "$old_passwd\r" }
}
expect "*node1*"
send "su - root\r"
expect "Password:"
send "$root_passwd\r"
expect "*node1*"
send "echo $new_passwd |passwd --stdin lianggj\r"
expect "*node1*"
send "exit\r"
expect "*node1*"
send "exit\r"
expect eof
3.执行主脚本
[root@node1 shell]# sh main_exec.sh
Starting script...
Please enter root password (or "Q" to quit): lahmy1c@
Processing IP: 192.168.10.30 for user: lianggj
Success: User modified on 192.168.10.30.
Processing IP: 192.168.10.31 for user: lianggj
Success: User modified on 192.168.10.31.
Processing IP: 192.168.10.32 for user: lianggjSuccess: User modified on 192.168.10.32.
Script execution completed. Logs available at: /root/monitor/log/mod_user_passwd.log
[root@node1 shell]#
6 结束语
expect是一个功能强大的自动化工具,特别适合处理需要用户输入的交互式任务,掌握 expect都能为你的工作带来极大的便利。希望本文能帮助入门expect,并在实际工作中灵活运用!