Shell脚本实战(二)
1、前言
此处旨在记录在实际工作中用到shell脚本,积累一些常用的用法,后续也可以参考。
2、功能点
因为项目原因,对外的sdk部署比较麻烦,一套操作下来,可能得一两个小时,为了提升效率和操作正确性,所以将操作整合成一个shell脚本,当前shell脚本主要涉及到的操作如下(只记录新增的功能):
- 定义全局变量,用于保存脚本日志
- 检测docker和docker-compose的安装状态
- 判断系统的某个服务是否启动
- 判断文件是否更新
- 只能输入指定范围内的数字
- 校验输入是否为IP
- 遍历文件夹
- 替换文件指定行内容
3、实际的脚本
#!/bin/bash #获取脚本所在文件夹 currentDir=$(cd $(dirname $0); pwd) current_time=$(date +"%Y-%m-%d %H:%M:%S") #定义全局变量 declare logFile=${currentDir}/installLog.log declare authIp="127.0.0.1" #检测网络联通 function checkNetStatus(){ echo -e "\e[32m 开始检测网络状态... \e[0m" >> ${logFile} 2>&1 ping -c 3 "user.cad.com" >> ${logFile} 2>&1 if [ $? -ne 0 ] then local netStatus=0 echo -e "\e[33m 无法连接外网,请采用离线模式授权,授权终止 \e[0m" >> ${logFile} 2>&1 else local netStatus=1 echo -e "\e[32m 可以联通外网,采用在线模式授权 \e[0m" >> ${logFile} 2>&1 fi return $netStatus } #检测Docker安装状态,未安装、部分安装、全部安装 function checkDockerStatus(){ echo -e "\e[32m 检测docker和docker-compose安装环境\e[0m" if ! [ -x "$(command -v docker)" ] then dockerStatus=0 echo -e "\e[33m 当前服务器未安装docker,尝试自动安装 \e[0m" else echo -e "\e[32m 当前服务器已经存在docker,跳过安装步骤 \e[0m" fi if ! [ -x "$(command -v docker-compose)" ] then dockerComposeStatus=0 echo -e "\e[33m 当前服务器未安装docker-compose,尝试自动安装 \e[0m" else echo -e "\e[32m 当前服务器已经存在docker-compose,跳过安装步骤 \e[0m" fi #安装docker和docker-compose if [ -n "$dockerStatus" ] && [ $dockerStatus -eq 0 ] then echo -e "\e[32m 开始安装docker和docker-compose组件... \e[0m" installDocker #安装docker会安装docker-compose,所以修改compose状态为已安装 dockerComposeStatus=1 fi if [ -n "$dockerComposeStatus" ] && [ $dockerComposeStatus -eq 0 ] then echo -e "\e[32m 开始安装docker-compose组件... \e[0m" installDockerCompose fi } function unzipPackages(){ echo -e "\e[32m 开始解压文件... \e[0m" #判断文件夹是否存在 if [ ! -d /home/cad ] then mkdir /home/cad fi if [ ! -d /home/cad/soft ] then mkdir /home/cad/soft fi if [ ! -d /home/cad/docker ] then mkdir /home/cad/docker fi #解压文件到指定文件夹 unzip -o 'Cloud2D_SDK.zip' -d ./Cloud2D_SDK >> ${logFile} 2>&1 #复制文件到指定文件夹下 cp ./Cloud2D_SDK/Cloud2D_SDK_API_Doc/docker-setup-offline.zip /home/cad/soft cp ./Cloud2D_SDK/Cloud2D_SDK_API_Doc/bit_service.zip /home/cad/soft cp -r ./Cloud2D_SDK/Cloud2D_FrontEnd_SDK/ExampleCode /home/cad/soft cp -r ./Cloud2D_SDK/Cloud2D_BackEnd_SDK/* /home/cad/docker cp ./Cloud2D_SDK/Cloud2D_BackEnd_SDK/.env /home/cad/docker #解压docker安装包、bitService安装包、cloud2dsdk安装包 unzip -o /home/cad/soft/docker-setup-offline.zip -d /home/cad/soft >> ${logFile} 2>&1 unzip -o /home/cad/soft/bit_service.zip -d /home/cad/soft >> ${logFile} 2>&1 echo -e "\e[32m 解压文件完成 \e[0m" } #安装Docker function installDocker(){ cd /home/cad/soft sh ./docker-runtime-offlinesetup.sh >> ${logFile} 2>&1 if ! [ -x "$(command -v docker)" ] then echo -e "\e[31m docker和docker-compose组件安装失败!!! \e[0m" else echo -e "\e[32m docker和docker-compose组件安装成功 \e[0m" fi } #安装Docker compose function installDockerCompose(){ cp -r /home/cad/soft/docker/docker-compose /usr/bin chmod 755 /usr/bin/docker-compose if ! [ -x "$(command -v docker-compose)" ] then echo -e "\e[31m docker-compose组件安装失败!!! \e[0m" else echo -e "\e[32m docker-compose组件安装成功 \e[0m" fi } #安装部署BitService function installBitService(){ if systemctl status bit_service >> ${logFile} 2>&1; then echo -e "\e[32m bit_service授权服务已经存在 \e[0m" else echo -e "\e[33m bit_service授权服务不存在,开始安装... \e[0m" cd /home/cad/soft chmod 755 ./bit_service.run sudo ./bit_service.run >> ${logFile} 2>&1 echo -e "\e[32m bit_service授权服务安装完成 \e[0m" systemctl enable bit_service systemctl start bit_service systemctl status bit_service >> ${logFile} 2>&1 fi #判断bitService是否启动成功 if systemctl status bit_service >> ${logFile} 2>&1; then echo -e "\e[32m bit_service授权服务启动成功 \e[0m" else echo -e "\e[31m bit_service授权服务启动失败!!! \e[0m" fi } #安装cloud2dSdk function installCloud2dSDK(){ echo -e "\e[32m 开始导入镜像和启动容器... \e[0m" cd /home/cad/docker docker load -i cadcoreservicesdk.tar >> ${logFile} 2>&1 docker-compose -f cadcoreservicesdk-compose-b-r.yaml up -d >> ${logFile} 2>&1 echo -e "\e[32m 容器启动完成 \e[0m" docker ps -a } #在线授权 function onlineActive(){ cd /opt/bitanswer/service ./bit_service -e /home/cad/soft/cad_.exm ./bit_service -a $1 } #部署前端文件 function copyFrontFile(){ echo -e "\e[32m 开始复制前端文件到docker容器... \e[0m" docker cp /home/cad/soft/ExampleCode/assets cadcoreservicesdk:/app/cadservice/wwwroot/ docker cp /home/cad/soft/ExampleCode/doc cadcoreservicesdk:/app/cadservice/wwwroot/ echo -e "\e[32m 开始复制前端文件到docker容器... \e[0m" } #配置前端代码中的服务器地址(私有化部署暂无配置服务器地址的操作) #判断压缩文件是否更新过 function checkUpdate(){ if [ ! -e $logFile ] || test $logFile -ot $currentDir/Cloud2D_SDK.zip then #需要安装 local updateStatus=0 else #不需要重新安装 local updateStatus=1 fi echo "脚本执行时间:$current_time" >> ${logFile} 2>&1 return $updateStatus } #重启docker容器 function restartDocker(){ echo -e "\e[32m 开始重启dokcer容器... \e[0m" docker stop cadcoreservicesdk >> ${logFile} 2>&1 cd /home/cad/docker docker-compose -f cadcoreservicesdk-compose-b-r.yaml up -d >> ${logFile} 2>&1 echo -e "\e[32m 重启完成 \e[0m" docker ps -a } #只允许输入指定范围的数字,$1表示起始值,$2表示结束值,$3表示输入值 function inputSpecificNumber(){ input=$3 while true; do expr $input "+" 10 &> /dev/null if [ $? -eq 0 ] then if [[ $input -ge $1 && $input -le $2 ]] then break; else read -p "只能输入数字,范围为$1-$2,请重新输入:" input; continue; fi else read -p "只能输入数字,范围为$1-$2,请重新输入:" input; continue; fi done return $input } #检验输入ip地址是否合法 function checkInPutIp(){ IP=$1 while true; do if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then ipCheck=$(echo $IP|awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}') if [[ -n $ipCheck && $ipCheck == "yes" ]]; then break; else read -p "IP地址不合法,请重新输入:" IP fi else read -p "IP地址不合法,请重新输入:" IP fi done authIp=$IP } #替换cfg中的授权文件ip和端口,存在多个文件夹时,遍历替换所有文件ip和端口 function replaceCfgIpAndPort(){ cfgPath='/home/cad/docker/cfg' ls $cfgPath | while read line do chmod -R 777 $cfgPath/$line sed -i "2s/.*/HostIP=$1/" $cfgPath/$line/float_config.ini sed -i "3s/.*/HostPort=$2/" $cfgPath/$line/float_config.ini done } #1、检测是否需要更新文件 checkUpdate updateStatus=$? #2、解压所有的安装包 if [ $updateStatus -eq 0 ] then unzipPackages else echo -e "\e[33m 压缩文件未发生变化,跳过解压步骤!!!... \e[0m" fi #3、安装docker和docker-compose checkDockerStatus #4、安装cloud2dSDK if [ $updateStatus -eq 0 ] then installCloud2dSDK else echo -e "\e[33m 镜像文件未发生变化,跳过启动docker容器步骤!!!... \e[0m" fi #5、处理授权服务 read -p "1:在当前服务器上安装授权客户端;2:直接使用其他服务器的授权客户端;3:不做任何处理;请输入1/2/3进行选择:" authType inputSpecificNumber 1 3 $authType authType=$? if [ $authType -eq 1 ] then #5-1、bit_service授权服务 installBitService #5-2、检测网络联通 checkNetStatus if [ $? -eq 1 ] then read -p "请输入授权码:" activeCode while [ -z $activeCode ] do read -p "授权码不能为空,请重新输入:" activeCode done echo -e "\e[32m 在线授权完成,授权结果如下: \e[0m" #5-3、在线激活授权 onlineActive $activeCode fi elif [ $authType -eq 2 ] then read -p "请输入授权客户端的服务器IP地址:" IP checkInPutIp $IP IP=$authIp read -p "请输入授权客户端的服务器端口,不输入则默认为(8273):" PORT if [ -z $PORT ] then PORT=8273 fi inputSpecificNumber 0 65535 $PORT #替换cfg授权文件的ip和端口 replaceCfgIpAndPort $IP $PORT else echo -e "\e[32m 不做任何处理,跳过安装授权服务步骤!!! \e[0m" fi #授权成功后,重启docker容器 restartDocker echo -e "\e[32m 所有程序部署完成,授权成功后,浏览器访问验证页面URL http://服务器IP:5121/index.html \e[0m"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通