相关知识点
-
expect
expect 是一个免费的编程工具,用来实现自动的交互式任务,而无需人为干预。
说白了,expect 就是一套用来实现自动交互功能的软件。
在实际工作中,我们运行命令、脚本或程序时,这些命令、脚本或程序都需要从终端输入某些继续运行的指令,而这些输入都需要人为的手工进行。而利用expect,则可以根据程序的提示,模拟标准输入提供给程序,从而实现自动化交互执行。这就是expect!!!
-
IFS
IFS是存储定界符的环境变量,是Shell环境中的默认定界符字符串,默认值为空白字符(换行符、制表符、空格)
效果预览
主要文件
goto.sh
#!/bin/bash
################################################
# 基于 shell 脚本,实现 ssh 自动登录操作
# Usage:
# 1. 修改 goto.conf ,追加服务器列表
# 2. $ chmod u+x goto.sh goto.ex
# 3. $ ./goto.sh
#
# 或使用如下方式将 goto 加入当前用户全局使用:
# $ echo "alias goto=\"$PWD/goto.sh\"" >> ~/.zshrc
# $ source ~/.zshrc
# $ goto
# Author: whoru.S.Q <whoru@sqiang.net>
# Version: 1.5
################################################
# 服务器列表文件
BASE_PATH=$(cd "$(dirname "$0")";pwd)
FILE_SERVER_LIST=$BASE_PATH"/goto.conf"
# 暂存服务器列表,用于登录操作
CONFIG_ARR=()
# 记录默认分隔符,用于修改后的还原
IFS_OLD=$IFS
# 初始化
function menu {
# 检查配置文件
if [ ! -f $FILE_SERVER_LIST ]; then
echo "Config file not found."
exit 1
fi
# 读取配置文件,显示待操作服务器列表
clear
echo "-------------------------------------"
local serverNum=1 # 服务器列表序号
local config=()
while read line || [ -n "$line" ]
do
if [[ ${line} != \#* && "$line" != "" ]] ; then
IFS=, # 定义读取配置文件时的分隔符
config=($line)
CONFIG_ARR[$serverNum]=$line
# serverName=$(echo $line | awk -F::: '{print $1}')
# serverIp=$(echo $line | awk -F::: '{print $3}')
spacenum=`expr 16 - ${#config[2]}`
spaces=$(seq -s ' ' $spacenum | sed 's/[0-9]//g')
echo -e " ${config[2]}$spaces- \033[32m$serverNum\033[0m.${config[0]}"
serverNum=$(($serverNum+1))
fi
done < $FILE_SERVER_LIST
IFS=$IFS_OLD # 还原分隔符
echo "-------------------------------------"
echo -en "请输入\033[32m序号\033[0m选择要登录的服务器: "
handleChoice ;
}
# 处理用户输入
function handleChoice {
read -n 1 choice
local serverListLength=${#CONFIG_ARR[@]}
if [[ "$choice" -lt 1 || "$choice" -gt serverListLength ]]; then
echo -en "\n\033[31m无效的序号[ $choice ], 是否重新输入( y 是 | n 否 ):\033[0m"
read -n 1 retry
if [[ -n "$retry" && "$retry" = "y" ]]; then
clear
menu ;
else
echo ""
exit 1
fi
else
sshLogin $choice;
fi
}
# 执行 ssh 登录
function sshLogin {
IFS=, # 定义读取分隔符
local config=(${CONFIG_ARR[$1]})
# 默认用户 root
local user=${config[1]}
if [[ $user == "" ]]; then
user="root"
fi
# 默认端口号 22
local port=${config[3]}
if [[ $port == "" ]]; then
port="22"
fi
# 开始登录
echo -e "\n\n\033[32m==>\033[0m 正在登录【\033[32m${config[0]}\033[0m】,请稍等...\n"
sleep 1
$(which expect) $BASE_PATH/goto.ex ${config[0]} ${config[2]} $port $user ${config[4]}
echo -e "\n\033[32m==>\033[0m 您已退出【\033[32m${config[0]}\033[0m】\n"
}
# 执行初始化
menu ;
goto.ex
#!/usr/bin/expect
set SERVER_NAME [lindex $argv 0]
set IP [lindex $argv 1]
set PORT [lindex $argv 2]
set USER_NAME [lindex $argv 3]
set PASSWORD [lindex $argv 4]
spawn ssh -p $PORT $USER_NAME@$IP
expect {
-timeout 300
"*assword" { send "$PASSWORD\r\n"; exp_continue ; sleep 3; }
"yes/no" { send \"yes\n\"; exp_continue; }
"Last*" {
puts "\n登录成功\n";
send "PROMPT_COMMAND='echo -ne \"\\033]0;$SERVER_NAME \\007\"' \r";
send "clear\r";
}
timeout { puts "Expect was timeout."; return }
}
interact
goto.conf
# 格式:hostname,user,ip,port,pwd,commands
# 参数说明:
# hostname 列表中显示的服务器名
# user 登录用户,默认 root
# ip 服务器 IP 地址
# port 登录端口号,默认 22
# pwd 登录密码
# commands 登录成功后,默认执行的命令,比如切换到指定目录
# 备注: 以 # 开头的行是注释,不会被读取
#
测试服务器,,192.168.1.56,,123456,cd /alidata/www && ls -l
更新地址:https://github.com/whorusq/ssh-autologin