首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

Linux下Shell脚本实现统一管理服务启停重启

编程知识
2024年09月13日 16:01

公司今年开始了大批量的裁员,人心惶惶,所以强迫自己学习点新知识,刚好领导给找了个事情,让写个脚本实现一键启停Linux服务器上的服务,于是开始研究这个怎么搞。

最开始的时候,有点想当然了,觉得一键启停不就是写个菜单,调用一下服务启动停止的命令就可以实现,但是在写的过程中,发现全是坑,搞的心态都崩了,所以目前先写了一个脚本应付一下领导,当然了这个脚本也比较简单,适用性也有一定的局限性,不过也还是可以参考复用的,我会把局限性在最下边做个简单的说明。

好了 废话不多说,直接上代码, 我会在关键的地方给写注释,说明一下方式方法,后边如果有不懂的评论就行        

#!/bin/bash

 

###################################

#                                 #

#       OWNER: 一袭白衣一         #

#                                 #

#       TIME:2024/8               #

#                                                                 #

#       version:1.0               #

#                                 #

###################################

 
#清屏,好看点,不多说了哈
clear
#声明个数组存储数据
declare -A services

 

#数组的样例哈
services=(
  ["服务1"]="服务所在的路径(到启动脚本所在的那一级),服务启动脚本所在路径(包含了启动脚本),服务名(进程里显示的那个),服务停止命令,打印日志所在路径(包含日志文件)"
  ["服务2"]="服务所在的路径(到启动脚本所在的那一级),服务启动脚本所在路径(包含了启动脚本),服务名(进程里显示的那个),服务停止命令,打印日志所在路径(包含日志文件)"
  ["服务3"]="服务所在的路径(到启动脚本所在的那一级),服务启动脚本所在路径(包含了启动脚本),服务名(进程里显示的那个),服务停止命令"

#后边可以放多个服务信息

)

#这块不多说了哈,就是去数组里获取启动脚本路径,调用启动命令启动服务
start_service() {
#声明一个变量从数组内拿相关信息,用于后边调用
  local service_path=$(echo ${services[$1]} | cut -d',' -f1)
  local start_script=$(echo ${services[$1]} | cut -d',' -f2)

  echo "Starting $1 at $service_path......"
  cd $service_path
  $start_script start || { echo "Failed to start $1"; return 1; }
}

 
#停止服务的模块,这部分有点特殊,我这边是因为有个服务的停止命令不是stop,是shutdown,所以做了个判断
#如果你们也有这样的情况,可以在这个地方做修改,没有的话,可以把中间的这个if拿掉
stop_service() {
#声明一个变量从数组内拿相关信息,用于后边调用
  local service_path=$(echo ${services[$1]} | cut -d',' -f1)
  local stop_script=$(echo ${services[$1]} | cut -d',' -f2)
  local service_name=$(echo ${services[$1]} | cut -d',' -f3)
  echo "Stopping $1 with: $service_path......"
  cd $service_path
#这个if模块不需要可以拿掉
  if [ "$service_name" == "特殊的服务" ];
  then
  $stop_script shutdown || { echo "Failed to stop $1"; return 1; }
else
  $stop_script stop || { echo "Faild to stop $1"; return 1; }
        fi
}

#重启模块了哈,这个就更简单, 我就是重复调用了一遍stop、start模块
restart_service() {

  local service_name=$1
#如果服务状态正常,就先停止,再启动,否则就直接启动
  if check_service_status $service_name; then
    stop_service $service_name
  fi
  start_service $service_name

}

#检查服务的状态,我这边用的是ps命令。直接查看进程里的服务是否存在,判断服务是否存活
check_service_status() {

  local process_name=$(echo ${services[$1]} | cut -d',' -f3)

  if pgrep -u $(whoami) -f "$process_name" > /dev/null; then
    echo "$1 is already running."

    return 0

  else

    echo "$1 is not running."

    return 1

  fi

}

 
#这块也是特殊服务用到的,有个服务启动的时间太长了所以必须要打印日志。。。。
#如果想让所有的服务都打印日志,可以在下边去掉判断,我会标注
#tail appserver&dbbackup log after them start

watch_log(){

   local service_name=$1

   local log_file=$(echo ${services[$service_name]} | cut -d',' -f5)

  if [ -n "$log_file" ];

   then

echo "Now Show log for $service_name: $log_file"

trap " echo 'Now Stop Show log for $service_name'; return" SIGINT

tail -f $log_file

else

  echo "No  log to show "

fi

}


#服务的list,用于check服务状态
service_processes_list() {

  for service in "${!services[@]}"; do
    echo "Showing the service processes for $service"
  check_service_status $service

  done

}

 
#主菜单展示,linux 的脚本就这样,丑点就丑点,好用就行
while true; do

  echo "#################################"

 

  echo "#****Services Control Menu******#"

 

  echo "#                               #"

 

  echo "#    1. Start Server            #"

 

  echo "#    2. Stop Server             #"

 

  echo "#    3. Restart Server          #"

 

  echo "#    4. Check Service status    #"

 

  echo "#    5. Exit menu               #"

 

  echo "#################################"

 

  read -p "Please select an option: " option

 
#进入实际的菜单功能模块了哈
  case $option in

    1)

      while true; do

        echo "Select a service to start:"

        select service in "${!services[@]}" "Back to main menu"; do

          case $service in

            "Back to main menu")

              break 2

              ;;

            *)

              if [ -n "$service" ]; then

                start_service $service

                sleep 3
#这个地方就是我说的特殊处理的,这两个特殊服务需要打印日志,不能仅通过进程判断是否启动正常
#如果想打印所有服务的日志,可以把这块的判断拿掉
                if [[ "$service" == "特殊服务1" || "$service" == "特殊服务2" ]];

                then

                 watch_log $service

                fi

                echo "Press any key to continue..."

                read -n 1 -s

                break

              else

                echo "Invalid option, please try again."


              fi

              ;;

          esac

        done

      done

      ;;

    2)

      while true; do

        echo "Select a service to stop:"

        select service in "${!services[@]}" "Back to main menu"; do

          case $service in

            "Back to main menu")

              break 2

              ;;

            *)

              if [ -n "$service" ]; then

                if check_service_status $service; then
#停止服务前,做了个提示,省的瞎搞误操作把生产环境服务停了。。。
                read -p "Are you sure want to stop $service ? (Y/N):" confirm

                if [ "$confirm" == "Y" ];

                then

                  stop_service $service

                sleep 3

                fi

                else

                  echo "$service is not running."

                fi

                echo "Press any key to continue..."

                read -n 1 -s

                break

              else

                echo "Invalid option, please try again."

              fi

              ;;

          esac

        done

      done

      ;;

    3)

    while true; do

        echo "Select a service to restart:"

        select service in "${!services[@]}" "Back to main menu"; do

          case $service in

            "Back to main menu")

              break 2

              ;;

            *)

              if [ -n "$service" ]; then

                restart_service $service

                sleep 3
#这个地方跟上边一样,就是专门给特殊服务做的,不需要可以拿掉
                if [[ "$service" == "特殊服务1" || "$service" == "特殊服务2" ]];

                then

                watch_log $service

                fi

                echo "Press any key to continue..."

                read -n 1 -s

                break

              else

                echo "Invalid option, please try again."

              fi

              ;;

          esac

        done

      done

      ;;

    4)

      service_processes_list

        sleep 3

      echo "Press any key to continue..."

      read -n 1 -s

      ;;

    5)

      exit 0

      ;;

    *)

      echo "Invalid option, please try again."

      ;;

  esac

done

上边的这个脚本,至少目前我在用的时候,是挺好用的,存在的不足后边在使用过程中一边发现一边更新吧,现在来说说这个脚本的局限性

第一:这个脚本如果在不修改代码的情况下,仅适用于启停命令为start  stop/shutdown的服务

第二:这个脚本暂时还无法记录操作日志,即谁执行的脚本,执行的记录暂时没有存储,所以只能说慎重操作

第三:这个脚本暂时没有添加一键启停模块,后边我会再做修改,争取增加一键启动停止重启的功能,这样更便于运维

第四:这个脚本如果想要跨服务器使用的话,需要修改对应的服务信息等,还是不够便携

 

说完不足了,说说后边的想法吧,这个脚本我还会进一步更新(如果能帮到大家的话,我会在论坛再次更新修改版),然后这个脚本实现的功能领导不太满意,领导觉得太麻烦,想让我搞个一键脚本,并且这个脚本适用于所有服务器,就是把脚本扔在任何一台服务器上,都可以运行。。。。(当然了,前提是我们自己的服务器)。

真是一个头两个大,后边想想怎么搞,目前已经有了一点思路,在这里也跟大家提前分享一下:

首先这个脚本想要适用所有的服务器(我们的),那首先脚本要识别服务器ip,不同的服务器上有不同的服务(例如主、备、BCP服务啊这些),那还要识别主、备这样的服务类别,其实这样的话,最好的方式是把所有服务的信息以及服务器信息放在一个文件内,通过脚本识别服务器,然后去读取文件里对应的信息,大概这样的话应该可以。

就先这样吧,后边有更新了再发,欢迎大家批评指导-。-

From:https://www.cnblogs.com/LangZiXiYan/p/18412527
本文地址: http://shuzixingkong.net/article/1984
0评论
提交 加载更多评论
其他文章 二分图最大权完美匹配
问题 给定一个二分图,左部有 \(n\) 个点,右部有 \(m\) 个点,边 \((u_i, v_j)\) 的边权为 \(A_{i,j}\)。求该二分图的最大权完美匹配。 转化 问题可以写成线性规划的形式,设 \(f_{i, j}\) 表示匹配中是否有边 \((u_i, v_j)\),求 \[\be
经典前端+后端+表头+表身的开发实战参考简易模板【珍藏】
前端部分(Vue 3 + Element Plus) 1. 修改 MPS002HList.vue(主生产计划列表) a. 添加查询表单 在模板中添加查询表单,包含产品料号、品名、规格和年月的输入项。 <template> <div> <!-- 查询表单 --> &
面试官:线程池遇到未处理的异常会崩溃吗?
首先,这个问题考察的是你对线程池 execute 方法和 submit 方法的理解,在 Java 线程池的使用中,我们可以通过 execute 方法或 submit 方法给线程池添加任务,但如果线程池中的程序在执行时,遇到了未处理的异常会怎么呢?接下来我们一起来看。 1.execute方法 exec
面试官:线程池遇到未处理的异常会崩溃吗? 面试官:线程池遇到未处理的异常会崩溃吗?
支付宝携手HarmonyOS SDK打造高效便捷的扫码支付体验
背景 在日常的购物转账、生活缴费等在线支付中,用户在正式拉起支付界面前,均需要至少经历一次"识别"+两次"寻找",即识别归属应用、寻找应用、寻找扫码入口,才能完成扫码、付款,每一步都带来不同程度的用户流失。如何将步骤繁琐的扫码支付做到最简化,是优化在线支付体验
支付宝携手HarmonyOS SDK打造高效便捷的扫码支付体验 支付宝携手HarmonyOS SDK打造高效便捷的扫码支付体验 支付宝携手HarmonyOS SDK打造高效便捷的扫码支付体验
架构师备考的一些思考(四)
前言 对于数学,我们之前学的是对的,但不是真的,所以我们没有数学思维。 对于计算机,我们学校教的是对的,但不是真的,所以仅仅从学校学习知识的应届毕业生,不论985,211,本科,专科都一样,都是一张白纸,啥也不会。 案例分析 案例分析是5选3,第一题必答。 问题一的类型 架构风格对比 问题二的类型
架构师备考的一些思考(四)
Python网页应用开发神器Dash 2.18.1稳定版本来啦
本文示例代码已上传至我的Github仓库:https://github.com/CNFeffery/dash-master Gitee同步仓库地址:https://gitee.com/cnfeffery/dash-master 大家好我是费老师,上周Dash发布了2.18.0新版本,并于今天发布了可
Python网页应用开发神器Dash 2.18.1稳定版本来啦 Python网页应用开发神器Dash 2.18.1稳定版本来啦 Python网页应用开发神器Dash 2.18.1稳定版本来啦
吊打面试官!从多维度理解架构
大家好,我是汤师爷~ 在工作当中,我们经常会听到以下说法: 产品负责人说,现在的业务架构太复杂,需要仔细梳理下。 技术领导说,这个项目很复杂,需要做下系统架构方案评审。 研发经理说,这次秒杀活动访问量非常大,需要用到高并发架构方案。 一线研发说,互联网大厂都会用到微服务架构,我要学学微服务架构设计。
吊打面试官!从多维度理解架构 吊打面试官!从多维度理解架构 吊打面试官!从多维度理解架构
使用 `Roslyn` 分析器和修复器 对异步方法规范化返回Async结尾
之前写过一篇使用修复器帮助添加头部注释文本的功能,今天使用Roslyn的代码修复器对异步返回方法规范化的功能 实现分析器 首先需要实现分析器,使用RegisterSyntaxNodeAction,分析所有SyntaxKind.MethodDeclaration的语法类型, [DiagnosticAn
使用 `Roslyn` 分析器和修复器 对异步方法规范化返回Async结尾 使用 `Roslyn` 分析器和修复器 对异步方法规范化返回Async结尾 使用 `Roslyn` 分析器和修复器 对异步方法规范化返回Async结尾