经常给各办事处客户现场打补丁或升级,面对十几上百台服务器,人工一台台替换肯定行不通,只能批量升级,将过程记录下来。
批量升级要解决的两个主要问题就是:
1.将补丁文件(安装包)上传到各服务器;
2.各服务器对收到的补丁文件自动进行升级。
下面详解各步骤:
1.批量上传文件 batch.sh
关键词 sshpass while
#!/bin/sh
list_file=host.list
src_file=$1
dest_file=/root
cat $list_file | while read line
do
host_ip=`echo $line | awk ‘{print $1}’`
host_port=`echo $line | awk ‘{print $2}’`
username=`echo $line | awk ‘{print $3}’`
password=`echo $line | awk ‘{print $4}’`
echo “$host_ip:$host_port”
sshpass -p $password scp -P $host_port $src_file $username@$host_ip:$dest_file
./expect_ssh.sh $host_ip $host_port $username $password $src_file
done
host.list文件里保存的是需要升级的服务器信息,while每次读取该文件一行获取到ip、端口、用户名、密码,再使用sshpass scp将目标文件传到服务器里。
目标文件(补丁)通过参数1传进来,保存在目标服务器的路径src_file,这里是/root
host.list:
10.88.10.11 22 root 123456
10.88.10.12 22 root 123456
10.88.10.13 22 root 123456
10.88.10.14 22 root 123456
10.88.10.15 22 root 123456
关于sshpass
ssh不能在登录命令行中带上密码直接登录,需要在出现提示后才可输入密码进行登录。sshpass的出现,解决了这一问题。sshpass用于非交互SSH的密码验证,可以使用 -p 参数指定明文密码,然后回车直接登录远程服务器,无须再次输入密码。它支持密码从命令行、文件、环境变量中读取。
登录:
# sshpass -p 123456 ssh root@192.168.13.111
传文件:
# sshpass -p 123456 scp -P 22 ./test_file root@192.168.13.111:/home
到这一步就把目标文件上传到指定的服务器了,接下来去完成一系列的升级操作,上面的例子里是去执行expect_ssh.sh脚本。
便于阅读和理解,这里将处理升级的操作单独放到一个脚本里完成。
2.自动升级
关键词 expect spawn
expect_ssh.sh
#!/usr/bin/expect
set host [lindex $argv 0]
set port [lindex $argv 1]
set username [lindex $argv 2]
set password [lindex $argv 3]
set packetname [lindex $argv 4]
set timeout 60
set cmd_prompt “]#|~]?”
spawn ssh -p $port $username@$host
expect {
-re “(yes/no)?” {
send “yes\r”
} -re “assword:” {
send “$password\r”
} -re “Permission denied, please try again.” {
exit
} -re “Connection refused” {
exit
} -re “Connection timed out” {
exit
} -re $cmd_prompt {
send “\r”
} eof {
exit
}
}
# now we do some commands
exec sleep 1
expect {
-re $cmd_prompt {
send “cd /root; rm -rf patch_pkg\r”
}
}
exec sleep 1
expect {
-re $cmd_prompt {
send “tar zxvf $packetname\r”
}
}
exec sleep 1
expect {
-re $cmd_prompt {
send “cd ./patch_pkg; ./update.sh\r”
}
}
exec sleep 1
expect {
-re “update success” {
send “exit\r”
}
}
exit
#interact
host、port、username、password、packetname是batch.sh中在执行./expect_ssh.sh时以参数传递进来的。
这里重点是expect、spawn的使用:
expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。expect的作者Don Libes在1990年开始编写Expect时对Expect做有如下定义:Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools)。使用它系统管理员 的可以创建脚本用来实现对命令或程序提供输入,而这些命令和程序是期望从终端(terminal)得到输入,一般来说这些输入都需要手工输入进行的。 Expect则可以根据程序的提示模拟标准输入提供给程序需要的输入来实现交互程序执行。
spawn ssh远程到服务器
expect{} 在括号里模拟交互的操作,-re捕获终端输出的内容最后关键词(不使用-re也可以),若存在,则利用send往终端发送命令,遇到报错,可以使用exit退出或自行定义其它操作。上述示例脚本里执行的操作流程是:远程到指定服务器;输入密码登录;进入到/root(第一步batch.sh里已经将补丁xxx.tar.gz放到/root路径),解压该文件;进入到解压出来的目录patch_pkg,执行里面的升级脚本update.sh。
基本思路就是这样,下一篇讲update.sh里的相关操作
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/178993.html