vlambda博客
学习文章列表

shell脚本控制服务的启动和关闭 - 具备详细案例

背景

最近工作中使用的自动化脚本涉及的一个功能是通过shell脚本来控制进程的重启(因为自己以前写过, 但是因为归纳总结做的不到位,导致找不到原来的笔记了)只能从网上搜下大概的,然后根据自己的理解重新整理下了, 整理的同时也复习了一下基本的shell脚本的编写, 做到温故知新!

本次的需求: 实现一个shell脚本来控制服务的启动, 如果该服务之前未运行, 通过该脚本可将服务运行起来;如果该服务已处于运行状态, 那么通过该脚本可将服务重新启动!

环境部署

本文使用的服务就拿tomcat服务来举例了, 毕竟这个服务下载和安装和部署都相对容易些

tomcat下载地址

https://downloads.apache.org/tomcat/tomcat-9/v9.0.62/bin/

tomcat部署

  1. 先解压文件 tar -zxvf apache-tomcat-9.0.62.tar.gz

  2. 进入目录, 运行tomcat cd apache-tomcat-9.0.62/binshell脚本控制服务的启动和关闭 - 具备详细案例

  3. 运行 启动命令: sh startup.sh 结束命令: sh shutdown.sh

  4. 预期结果 + 可能报错

「预期结果」
通过ps -ef|grep tomcat 命令, 即可查看到tomcat进程信息shell脚本控制服务的启动和关闭 - 具备详细案例

「最常见的报错」
8080端口被占用了,因为tomcat默认端口就是8080 此时可以通过 lsof -i:8080, 找到该进程的pid, 然后kill -9 pid即可结束掉该进程, 重新运行 sh startup.sh 即可

重启tomcat的shell脚本

自己调试的最终版本代码如下

pid=$(ps -ef | grep tomcat|grep -v grep| awk '{print $2}')

if [ ! -z "$pid" ];then
  echo "当前运行tomcat服务的pid是: ${pid}"
  kill -9 ${pid}
  echo -e "已结束当前tomcat服务~\n"
else
  echo -e "目前未运行tomcat服务!\n" 
fi

sh startup.sh

echo -e "\n"
pid1=$(ps -ef | grep tomcat|grep -v grep| awk '{print $2}')

if [ ! -z "$pid1" ];then
  echo "已重启tomcat服务( * ̄▽ ̄)"
  echo "tomcat服务新的pid是: ${pid1}"
else
  echo "重启tomcat服务失败, 请检查是不是8080端口被占用了(>﹏<)"
fi

将上述代码命名为restart.sh, 放在了tomcat的bin目录下

  • 测试场景 - 之前「未」启动服务,此时运行该脚本shell脚本控制服务的启动和关闭 - 具备详细案例

  • 测试场景 - 之前「已」启动服务,此时运行该脚本

本次的shell代码知识点

ps -ef 那一长串命令的解释

ps -ef | grep tomcat|grep -v grep| awk '{print $2}'
  1. 首先 ps -ef | grep tomcat是过滤当前系统中, 带有tomcat关键字的所有进程
  2. 由上图可见, 查询出来2条进程, 一个是预期的tomcat进程,另一个是我们过滤的grep进程.我们需要把grep进程过滤掉, 所以使用 grep -v grep
  • 备注: grep -v 是反向查找的意思,比如 grep -v grep 就是查找不含有 grep 字段的行
  1. 经过上述操作,我们仅查出来一个预期进程, 我们目标是获取以空格分割的的第二列数据 27851 这个进程号, 所以使用到了awk命令
  • 备注: 传闻Linux中有三剑客: grep, sed, awk.这里用到的awk是linux三剑客之一!
  • awk的使用场景是想获取以某个分隔符分割的数据,这个分隔符默认是空格.       print $2 代表取第2列的数据,即当前场景的进程号 27851

shell中为变量赋值 和 取值

使用的是$()$变量 这两种用法

  1. 基本示例示例
a=$(date)
echo $a  # Wed Apr 20 20:50:48 CST 2022
  1. tomcat的shell脚本中

pid=$(ps -ef | grep tomcat|grep -v grep| awk '{print $2}')即将各种操作后得到的pid赋值给pid变量

shell判空

if [ ! -z "$pid" ];then这句代码里面用到了判空的用法, 如果 从pid变量取出的值为空, 那么if [ -z "$pid" ];then 就为True, 加上!, 代表去反则为False

pid=$(ps -ef | grep tomcat|grep -v grep| awk '{print $2}')

if [ ! -z "$pid" ];then
  echo "当前运行tomcat服务的pid是: ${pid}"
  kill -9 ${pid}
  echo -e "已结束当前tomcat服务~\n"
else
  echo -e "目前未运行tomcat服务!\n" 
fi

在本代码块中, 如果能查找到tomcat的pid, 那么if [ -z "$pid" ];then为Fasel, 去反为True, 进入到then后面的判断语句, 根据tomcat的pid结束掉tomcat进程

shell的其它小细节

  1. 「双引号 和 单引号的区别」

双引号: 里面可以调用变量, 相当于动态使用变量.if [ ! -z "$pid" ]可以动态的获取pid变量的值放入判断语句中

单引号: 将里面的内容就认为是一个字符串, 不会动态的使用里面的变量的值.例如,echo '$pid',输出结果为 $pid

  1. 「shell脚本中输出换行符」

一开始以为直接这样既可echo "hello world\n", 发现并不可以, 必须这样使用echo -e "hello world\n".其中-e参数代表激活转义字符