🦄 个人主页------🎐 个人主页 🎐✨🍁
🪁🍁🪁🍁🪁🍁🪁🍁 感谢点赞和关注 ,每天进步一点点!加油!🪁🍁🪁🍁🪁🍁🪁🍁
目录
[1.1 命令简介](#1.1 命令简介)
[1.2 使用场景](#1.2 使用场景)
[1.3 expect命令安装](#1.3 expect命令安装)
[2.1 命令原理介绍](#2.1 命令原理介绍)
[3.1 expect 启用选项](#3.1 expect 启用选项)
[3.2 .expect命令参数](#3.2 .expect命令参数)
[4.1 登录远程服务器并在远程服务器上执行命令](#4.1 登录远程服务器并在远程服务器上执行命令)
[4.2 本机免密实现](#4.2 本机免密实现)
[4.3 自动生成kerberos用户的keytab认证文件](#4.3 自动生成kerberos用户的keytab认证文件)
一、概述
1.1 命令简介
expect 是由Don Libes基于Tcl(Tool Command Language )语言开发的,是一种脚本语言,主要应用于自动化交互式操作的场景,借助Expect处理交互的命令,可以将交互过程如:ssh登录,ftp登录等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率。
1.2 使用场景
(1)根据预定标准回答其问题,回答"是"、"否"或将控制权交还给您
(2)远程连接设备并执行自动化操作
(3)需要人机交互的地方,如果提前知道应该输入什么指令都可以使用expect 工具
1.3 expect命令安装
yum install expect -y
二、expect使用原理
2.1 命令原理介绍
spawn启动指定进程---expect获取指定关键字---send向指定程序发送指定字符---执行完成退出
- spawn命令
spawm命令就是用来启动新的进程的。spawn后的send和expect命令都是和spawn打开的进程进行交互的、
- send命令
send命令接收一个字符串参数,并将该参数发送到进程,这个过程类似模拟人类输入密码
- interact命令
结合spawn、expect、send自动化的完成很多任务,interact命令可以在适当的时候进行任务的干预,比如下载完ftp文件时,仍然可以停留在ftp命令行状态,以便手动的执行后续命令
三、expect使用语法
3.1 expect 启用选项
- -c 执行脚本前先执行的命令,可多次使用
- -d debug模式,可以在运行时输出一些诊断信息,与在脚本开始处使用exp_internal 1相似。
- -D 启用交换调式器,可设一整数参数。
- -f 从文件读取命令,仅用于使用#!时。如果文件名为"-",则从stdin读取(使用"./-"从文件名为-的文件读取)。
- -i 交互式输入命令,使用"exit"或"EOF"退出输入状态
- -- 标示选项结束(如果你需要传递与expect选项相似的参数给脚本时),可放到#!行:#!/usr/bin/expect --
- -v 显示expect版本信息
3.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 输出变量
四、实战案例
4.1 登录远程服务器并在远程服务器上执行命令
bash
#!/usr/bin/expect
spawn ssh root@192.168.2.161 df -h
expect "*password:"
send "winner@001\n"
expect eof
执行结果如下图:
4.2 本机免密实现
bash
#! /bin/bash
#
# Author: kangll
# CreateTime: 2023-11-10
# Desc: 基础环境配置,包括服务器设置,JDK,免密,kerberos配置
# 可扩展到批量操作
#
#set -x
BASEDIR=$(cd "$(dirname "$0")"; pwd)
# 加载配置
source $BASEDIR/config/global.sh
ssh_networkname=(windp-aio)
ssh_passwd=winner@#2023
########################
# 生成本地ssh公钥
########################
create_ssh_pub(){
echo "生成本地ssh公钥"
/usr/bin/expect << eof
# 设置捕获字符串后,期待回复的超时时间
set timeout 30
# 执行命令开启一个新的进程
spawn ssh-keygen -t rsa -b 1024
## 开始进连续捕获
expect {
".ssh/id_rsa)" { send "\n"; exp_continue }
"Overwrite (y/n)?" { send "y\n"; exp_continue }
"no passphrase):" { send "\n"; exp_continue }
"passphrase again:" { send "\n"; exp_continue }
}
eof
}
########################
# 定义复制ssh公钥方法
########################
copy_ssh(){
if [ ! -f /root/.ssh/id_rsa.pub ];then
create_ssh_pub
fi
echo "复制公钥到对应的主机上"
/usr/bin/expect << eof
# 设置捕获字符串后,期待回复的超时时间
set timeout 30
# 命令执行
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $1@$2
## 开始进连续捕获
expect {
"connecting (yes/no)?" { send "yes\n"; exp_continue }
"s password:" { send "${ssh_passwd}\n"; exp_continue }
}
eof
}
########################
# 配置免密
########################
config_ssh() {
# 主机遍历
for name in ${ssh_networkname[*]};do
timeout 5 ssh root@${name} "echo ${name}: 'This is success!'"
if [[ $? -ne 0 ]];then
echo "复制文件到: ${name}"
copy_ssh root ${name} > /dev/null
fi
done
echo "********** ssh installation completed **********"
}
# 配置root用户免密
config_ssh
4.3 自动生成kerberos用户的keytab认证文件
bash
#! /bin/bash
#
# Author: kangll
# CreateTime: 2023-11-10
# Desc: 基础环境配置,包括服务器设置,JDK,免密,kerberos配置
# 可扩展到批量操作
#
# public 主机名和root密码
ip=$(ip addr show | grep -E 'inet [0-9]' | awk '{print $2}' | awk -F '/' '{print $1}' | sed -n '$p')
ssh_hosts=${ip}
ssh_networkname=(windp-aio)
# global.sh 配置文件中获取
ssh_passwd=$root_passwd
ssh_passwd=winner@#2023
kerberos_user=winner_spark
##################################
# 配置kerberos用户: winner_spark
# 生成keytab 文件
##################################
config_kerberos_user() {
echo "******** 创建winner_spark用户实例 ********"
/usr/bin/expect << eof
# 设置捕获字符串后,期待回复的超时时间
set timeout 30
# 登录
spawn kadmin.local
## 开始进连续捕获,添加用户
expect {
"kadmin.local:" { send "addprinc ${kerberos_user}\n"; exp_continue }
"Enter password for principal" { send "${ssh_passwd}\n"; exp_continue }
"Re-enter password for principal" { send "${ssh_passwd}\n"; }
}
expect "kadmin.local:" { send "quit\r"; }
eof
echo "******** winner_spark用户生成keytab文件 ********"
/usr/bin/expect << eof
# 设置捕获字符串后,期待回复的超时时间
set timeout 30
spawn kadmin.local
## 开始进连续捕获,生成keytab file
expect {
"kadmin.local:" { send "xst -k /etc/security/keytabs/${kerberos_user}.keytab ${kerberos_user}@WINNER.COM\n"; }
}
expect "kadmin.local:" { send "quit\r"; }
eof
# modify keytab file privilege
chown ${kerberos_user}:hadoop /etc/security/keytabs/${kerberos_user}.keytab
echo "********** kerberos user winner_spark add completed **********"
}
# 配置kerberos,并启动
#config_krb5
# 配置kerberos用户: winner_spark, 生成keytab 文件
config_kerberos_user