近期有个小伙伴邀请我去回答问题linux中如何关闭后台运行的sh脚本
回到完问题后,我觉得可以基于这个话题,写一个更完备一点的实现思路供大家参考。

使用场景说明

在服务器上管理服务时我们经常需要启动、停止、重启脚本。
启动脚本时需要设置一些运行时的环境、指定运行时的一些参数等,如果每次启动脚本都是都逐一输入会比较麻烦,那么我们就可以把这些固定的流程都写入脚本中,启动时一键命令启动即可。
停止脚本也是一样,我们一般需要ps找到运行的进程号,确认是我们的脚本后再执行kill。这些过程也都可以自动化。

脚本示例与说明

代码地址

# 获取脚本所在的目录
CUR_DIR=$(dirname $0)
# 进入到该目录运行,这样可以规避绝对路径的问题,你的脚本迁移到任何目录都可以正常运行
cd ${CUR_DIR}# 该函数running正常退出,not running则退出非0值
check_server_is_running() {[[ ! -f "pid" ]] && touch pid# 获取PID=$(cat pid)# 首先判断pid是否存在if [ "${PID}" = "" ]thenecho "server is not running."return 1fi# 再判断指定的PID是否在当前目录运行,防止因历史异常原因遗留了失效PID,正好该PID又被其他进程占用,造成误杀。if [[ -d /proc/${PID}/cwd ]] && ls -ahl /proc/${PID}/cwd | grep -q "${CUR_DIR}"thenecho "server is running."return 0else# 清空失效的进程号并异常退出echo "" > pidreturn 1fi
}start() {# 启动前判断日志目录是否存在,不存在就创建[[ ! -d "../logs" ]] && mkdir -p ../logs# 启动服务sh test.sh > ../logs/start.log 2>&1 &# 保存PID,以供stop使用PID=$!echo "server start succ, PID=${PID}!"echo "${PID}" > pid
}stop() {# get pidPID=$(cat pid)kill -9 ${PID}
}case C"$1" inCstart)check_server_is_running || startecho "start done.";;Cstop)check_server_is_running && stopecho "stop done.";;Crestart)check_server_is_running && stop || startecho "restart done.";;C*)echo "Usage: $0 {start|stop|restart}";;
esac

代码释义(供新手参考)

  • 0 与 0与 0与!
    $0 在shell脚本中指当前运行的脚本本身,$1就是脚本的第一个参数,依次类推,$2就是传给脚本的第二个参数。
    $! 在shell中可以获取上一个命令的进程号,这个脚本中服务启动成功后的进程号就是通过这个参数获取并保存到一个文件的。

  • dirname
    该命令可以获取文件所在的目录,最常见的用法就是 dirname $0获取当前脚本所在的目录。并且cd到这个目录中。
    脚本中我们经常使用相对路径,这样编写的脚本就不会收到程序的绝对路径影响。

  • &&和||
    在shell中我们经常执行一个命令时需要依赖上一个命令的执行情况。
    譬如启动脚本程序,我们启动前需要判断当前程序是否在运行,在运行我们就不重新启动,没有运行我们就启动。
    此处我们用的是check_server_is_running || start
    cmd1||cmd2连接的两个命令的执行关系是。cmd1执行成功(程序退出码为0)就不执行cmd2,执行失败(程序退出码非0)才执行cmd2.
    cmd1&&cmd2连接的两个命令的执行关系与上面刚好相反。cmd1执行成功(程序退出码为0)才执行cmd2,执行失败(程序退出码非0)就不执行cmd2.

  • 判断语句
    本脚本里面用了2种判断语句,if判断语句和[[ 判断语句 ]]
    if与很多其他语言里面的一样。
    [[ 判断语句 ]] 是一种快捷判断方式,它与 || 或者 && 符号组合使用就可以到达if else的效果。

  • proc文件系统
    linux系统中一切都是文件,/proc目录下存储的就是系统正在运行的程序的各种资源使用情况。
    proc文件系统是linux的一种虚拟文件系统,只存储在内存中,只有正在运行中的程序采用。
    /proc/${PID}目录下可以看到进程 P I D 的所有运行情况。 ‘ / p r o c / {PID}的所有运行情况。 `/proc/ PID的所有运行情况。‘/proc/{PID}/cwd`是进程${PID}所在的目录,上面的程序就是通过这个目录来增强校验,防止异常情况(譬如手动kill或者程序异常退出,pid文件的PID没有被清除,正好这个PID被重新分配给了其他进程)时,造成误杀。

  • grep -q
    grep -q通常与if语句一起使用,grep -q 匹配成功就是true,匹配失败就是false

  • shell脚本的 switch语句
    case esac就等同于其他语言的switch语句。
    脚本在所有的字符判断前面加了一个C就是为了防止输入的参数为空,让系统误以为缺失参数,可能带来语法错误的问题。
    我们在写shell脚本时为了兼容空字符串可能带来语法错误的问题,经常会给参与比较的对象统一加一个前缀字符。

linux启动停止脚本实现相关推荐

  1. 【转】Linux Oracle服务启动停止脚本与开机自启动

    在CentOS 6.3下安装完Oracle 10g R2,重开机之后,你会发现Oracle没有自行启动,这是正常的,因为在Linux下安装Oracle的确不会自行启动,必须要自行设置相关参数,首先先介 ...

  2. Linux Oracle服务启动停止脚本与开机自启动[转]

    在CentOS 6.3下安装完Oracle 10g R2,重开机之后,你会发现Oracle没有自行启动,这是正常的,因为在Linux下安装Oracle的确不会自行启动,必须要自行设定相关参数,首先先介 ...

  3. linux停止jar程序,Linux 启动停止SpringBoot jar 程序部署Shell 脚本的方法

    废话不多说了,先给大家上代码,具体代码如下所示: #!/bin/bash cd `dirname $0` CUR_SHELL_DIR=`pwd` CUR_SHELL_NAME=`basename ${ ...

  4. Linux Oracle服务启动停止脚本与开机自启动

    在CentOS 6.3下安装完Oracle 10g R2,重开机之后,你会发现Oracle没有自行启动,这是正常的,因为在Linux下安装Oracle的确不会自行启动,必须要自行设定相关参数,首先先介 ...

  5. linux启动脚本springboot,Linux 启动停止SpringBoot jar 程序部署Shell 脚本的方法

    废话不多说了,先给大家上代码,具体代码如下所示: #!/bin/bash cd `dirname $0` cur_shell_dir=`pwd` cur_shell_name=`basename ${ ...

  6. python后端脚本停止运行_Python 启动/停止脚本(后台服务)

    简述 之前,用 Python/Tornado(Web 服务器框架)实现了一个 LDAP 相关的后台组件,用于客户端的用户认证. 若用命令行方式启动脚本,十分简单: # python web_serve ...

  7. linux logo程序,生成linux启动logo脚本

    一.生成linux启动logo脚本 #!/bin/sh pngtopnm logo.png | ppmquant -fs 224 | pnmtoplainpnm > logo_linux_clu ...

  8. linux启动关闭脚本,Linux中启动/停止/重启/状态的startup脚本

    今天看到一个脚本,可以完成脚本的启动/停止/重启/状态,和/etc/init.d中的服务一样.但是/etc/init.d里面的服务要设置开机启动,可以使用service来管理.如果不设置开机启动且方便 ...

  9. linux启动/停止/重启MySQL的命令

    linux如何启动/停止/重启MySQL数据库服务?两种方式,一种是使用service启动/停止/重启,另一种则是使用mysqld脚本启动/停止/重启. linux启动MySQL命令 [root@yu ...

最新文章

  1. 为了一个科研idea,博士生们连冥想、巫毒仪式都用上了
  2. 如何制定一份永远完不成的年度计划?
  3. AngularJS---核心特性
  4. 发文平台对文章发布的基本要求
  5. 北邮OJ 1010. 16校赛-Binary Strings
  6. 深度解密Go语言之sync.map
  7. MinIO存储桶通知指南 ​​​​​​​
  8. Spark基础学习笔记07:搭建Spark HA集群
  9. 用js实现分页功能以及利用xml实现分页功能——数据岛
  10. 35张史上最全IT架构师技术知识图谱
  11. H5自定义属性详细介绍
  12. JVM中也有并发GC,CMS机制
  13. R语言dplyr入门到进阶
  14. Centos下搭建个人网站
  15. 信号完整性七步曲:从PCB走线、信号反射到特性阻抗
  16. C语言课程设计 管理系统
  17. android 音频合并
  18. 运行老项目报错 opensslErrorStack: [ ‘error:03000086:digital envelope routines::initialization error‘ ].....
  19. 杰瑞学Perl之CPAN(1)
  20. Win10添加开机自动运行软件三种方法(亲测可用)

热门文章

  1. 从情境中学习数据分析,体会数据分析逻辑。今天给大家分享的案例是关于美食
  2. Git冲突:Please commit your changes or stash them before you merge
  3. [转]惠普知识管理的前世今生
  4. 人妖为什么要和美女打架?
  5. 总结-Java多线程与高并发简记
  6. 迄今为止跑得最快的一次10公里
  7. 爱茉莉太平洋旗下品牌芙莉美娜正式进入中国市场
  8. 主成分分析应用实例(Matlab):鸢尾花分类
  9. 2022年终总结, 2023 年度规划
  10. MySQL之数据库设计六个步骤