一、问题背景:
实际开发过程中,有多套环境,每次修改代码时,需要更新多套环境,很费时费力,之前是打好包之后挨个服务器去传,然后打开xshell,连接这几台服务器,然后点xshell的选项卡→排列→瓷砖排列,再点工具→发送键输入到所有会话,然后再cd到目录中,执行我们启动jar包的脚本可以简单理解为java -jar
,整个流程非常麻烦。
二、问题解决流程:
GPT+必应
GPT提供batchUpdate.sh
的绝大部分代码。(在linux写脚本,脚本可以同时在几个不同的服务器上的/a/b目录下上传c.jar并且运行java -jar c.jar,servers内的服务器有多个,可以在运行脚本的时候指定,jar包名称需要参数指定,没有设置无密码登录,需要把密码写在脚本里怎么写)
必应查一些需要的安装包以及如何安装。
参考:
https://blog.csdn.net/wangtaoking1/article/details/78268574
包下载:
https://sourceforge.net/projects/tcl/files/Tcl/8.4.19/tcl8.4.19-src.tar.gz/download
https://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz/download
注意事项:
1、如果这些服务器启动jar包的用户及用户密码不一样,那无法用我这个脚本,不用往下看了。
2、第一次执行 batchUpdate.sh
脚本时,会输入两次yes,一次用户密码,来安装好像是签名,公钥之类的东西,每个服务器第一次ssh都要安装一下。之后再执行就不用了,就比较丝滑了。
三、准备工作。
# 先检查服务器有没有安装过expect,安装过就别在这浪费时间了。
# 友情提示,如果以前安装过,但是没指定路径--prefix=,那就只能用root用户执行脚本了,因为他好像是默认往/usr里面安装。
whereis expect
# 上传tcl8.4.19-src.tar.gz和expect5.45.tar.gz到/home/xxx目录下。
# 安装tcl
tar -zxvf tcl8.4.19-src.tar.gz
mkdir /home/xxx/tcl
cd /home/xxx/tcl8.4.19/unix
./configure --prefix=/home/xxx/tcl
make
make install
# 安装expect
tar -zxvf expect5.45.tar.gz
mkdir /home/xxx/expect
cd /home/xxx/expect5.45
./configure --prefix=/home/xxx/expect --with-tcl=/home/xxx/tcl/lib --with-tclinclude=../tcl8.4.19/generic
make
make install
# 上传batchUpdate.sh和要更新的jar包 到/home/xxx目录下。
# 执行脚本去批量更新jar包。例如: ./batchUpdate.sh abc.jar 192.168.1.100 192.168.1.101 192.168.1.102
cd /home/xxx
vim batchUpdate.sh
chmod 755 ./batchUpdate.sh
./batchUpdate.sh <jar_path> <server1> [<server2>,<server3> ...]
四、batchUpdate.sh,批量更新多个linux服务器的jar包脚本。
#!/bin/bash
# 注意这里的几个空格,建议直接复制。
if [ "$#" -lt 2 ]; then
echo "Usage: $0 <jar_path> <server1> [<server2>,<server3> ...]"
exit 1
fi
jar_path="$1"
# 改成自己服务器的密码。
password="wozhenshuai"
shift
# 里面的 /home/xxx 和 username 改成自己要用的。
# echo内容想写啥写啥,告诉自己脚本现在到哪步了。
for server in "$@"; do
echo "Uploading $jar_path to $server:/home/xxx"
expect -c "
spawn scp "$jar_path" username@"$server":/home/xxx
expect \"password:\"
send \"$password\r\"
interact
"
echo "Running $jar_path on $server"
expect -c "
# 这里因为我的需求是调用各个服务器的某个脚本去启动jar,所以我这里调了脚本。
# 如果你只是比较简单的启动nohup java -jar 那就自己换一下命令,包括再 && tailf看下日志之类的。
spawn ssh username@"$server" \"cd /home/xxx && ./xxx.sh\"
expect \"password:\"
send \"$password\r\"
interact
"
# echo内容这里想写啥写啥,告诉自己当前这台服务器$server更新jar包完成了。
echo "-------------------- $server 处理完成 --------------------"
done
# echo内容这里想写啥写啥,就主要告诉自己这个脚本执行完成了。
echo "done"
五、踩坑
在执行 batchUpdate.sh
脚本时报错,我其他服务器上的xxx.sh
里面做了一些启动jar包判断启动状态以及备份的处理等。
/home/xxx/xxx.sh 行xx: jps: 未找到命令
/home/xxx/xxx.sh 行xx: java: 未找到命令
无法stat:没有那个文件或目录
tar: 由于前次错误,将以上次的错误状态退出
解决:
把xxx.sh
中涉及到java的相关指令,比如jps,java
,前面都加上当前linux服务器java目录的绝对路径。
一开始想的是用pgrep
之类的命令能不能给jps
替换掉(这里浪费了挺多时间),后来搜了一下发现换成绝对路径就可以了。
例如:
# 查询java路径,这个路径粘贴到比如jps前面后,记得加 /bin ,因为jps,java等命令在你$JAVA_HOME的bin目录下
echo $JAVA_HOME
jps -lm →→ /home/xxx/jdk/bin/jps -lm
nohup java →→ nohup /home/xxx/jdk/bin/java