返回顶部
首页 > 资讯 > 精选 >如何正经的实现shell脚本单例运行
  • 481
分享到

如何正经的实现shell脚本单例运行

2023-06-16 00:06:21 481人浏览 八月长安
摘要

这篇文章将为大家详细讲解有关如何正经的实现shell脚本单例运行,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。看起来可行的方法一个非常简单的思路就是,新的脚本被执行时,先检测当前脚本是否有其他实例正在运行

这篇文章将为大家详细讲解有关如何正经的实现shell脚本单例运行,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

看起来可行的方法

一个非常简单的思路就是,新的脚本被执行时,先检测当前脚本是否有其他实例正在运行,如果有则直接退出。

runCount=$(ps -ef|grep test.sh | grep -v grep -c) if [ "${runCount}" -ge 1 ] then     echo -e "test.sh already running,num:${runCount}"     exit 1; fi while true do     echo "test.sh run"     sleep 1 done

这里通过ps获取到当前在运行的test.sh脚本数,如果大于1,说明已经有在运行的了。

但是你运行会发现,其程序数量不只是一个。

$ ./test.sh test.sh already running,num:2

惊不惊喜?为什么为这样呢?原因在于,shell脚本中一个命令执行相当于fork了一个进程执行,这里执行的是查找tesh.sh并grep的程序,另外还有一个就是当前运行的脚本程序,这样的方式自然就会出现每次都有两个了。

当然判断条件这里你可以换一下,例如数量大于2,但终归不太好。

文件锁

实际上这种方法你已经在《如何让你的程序同时只有一个在运行》介绍过了,只不过之前是用于编写C/C++程序,而这里是用于shell脚本。

我们来回顾一下,这是一个怎样的过程:

  • 运行前检查是否有该文件,并且文件中的进程正在运行

  • 如果有并且程序正在运行,则已经有实例在运行

  • 否则,无实例,创建锁文件,写入进程id

  • 退出时,删除锁文件

解释一下第一条,为什么一定要确定锁文件中的进程正在运行,因为,有些情况下如果运行的时候退出没有删除该文件,则会导致新的实例永远无法运行。

#!/usr/bin/env bash LOCKFILE=/tmp/test.lock if [ -e ${LOCKFILE} ] && kill -0 `cat ${LOCKFILE}`; then     echo " $0 already running"     exit fi  # 确保退出时,锁文件被删除 trap "rm -f ${LOCKFILE}; exit" INT TERM EXIT #将当前程序进程id写入锁文件 echo $$ > ${LOCKFILE}  # 做你需要的事情 sleep 1000  # 删除锁文件 rm -f ${LOCKFILE}

我们试着运行其中一个,然后另外一个窗口尝试运行:

$ ./test.sh  ./test.sh already running

由于已经有实例在运行,发现新的程序无法运行了。而等旧的脚本运行完之后,新的就可以运行了。

实际上这里面有几个点非常巧妙:

  • kill -0 `cat \${LOCKFILE}` 这里用于检测该进程是否存在,避免进程不在了,但是锁文件还在,导致后面的脚本无法运行。

  • trap "rm -f \${LOCKFILE}; exit" INT TERM EXIT 用于确保脚本退出时,锁文件会被删除。

  • rm -f {LOCKFILE} 脚本最后需要删除锁文件

flock

说到锁文件,这里就不得不提flock命令了。没有前面的一些巧妙处理,我们很多时候会很难删除原先创建的锁文件,比如:

  • 脚本被意外中断,没来得及执行删除

  • 多个脚本产生竞争,导致判断异常,比如前面有一个脚本运行,判断没有锁文件,下一步准备创建,但是另外一个脚本又先创建了,就会导致异常了。

因此我们可以考虑使用flock:

#!/usr/bin/env bash LOCK_FILE=/tmp/test.lock exec 99>"$LOCK_FILE" flock -n 99 if [ "$?" != 0 ]; then     echo "$0 already running"     exit 1 fi #脚本要做的其他事情 sleep 1024

解释一下:

  • exec 99>"$LOCK_FILE"  表示创建文件描述符99,指向锁文件,为何是99?110其实也是可以的,只是为了和当前脚本可能打开的文件描述符冲突(例如和0,1,2冲突)。

  • flock -n 99 尝试对该文件描述符加锁,由操作系统保证原子性

  • 一旦flock失败了,我们这里可以退出

  • 而即使锁定了,脚本退出后,也会自动释放

因此这里避免了锁没有释放的情况。

另一种做法

查看flock的man手册,我们发现它还有一个例子是这么做的:

[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en  "$0"  "$0"  "$@" || :

在脚本开头加上上面这么一行就可以了。例如:

#!/usr/bin/env bash [ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en  "$0"  "$0"  "$@" || : #脚本要做的其他事情 sleep 1024

解释一下:如果${FLOCKER}环境变量没有设置,则尝试将脚本本身加锁,如果加锁成功,则运行当前脚本,(并且带上原有的参数),否则的话静默退出。

总结

单例运行本身思路是很简单的,就是探测当前是否有实例在运行,如果有,则退出,但是这里如何判断,却并不是那么容易。

最后,总结一下本文出现的一些该掌握的信息:

  • $0 脚本名称

  • $@ 脚本参数

  • $$ 当前脚本进程id

  • $? 上一条命令执行结果

  • 描述符0 标准输入

  • 描述符1 标准输出

  • 描述符2 标准错误

  • > 重定向

关于“如何正经的实现shell脚本单例运行”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: 如何正经的实现shell脚本单例运行

本文链接: https://lsjlt.com/news/281964.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何正经的实现shell脚本单例运行
    这篇文章将为大家详细讲解有关如何正经的实现shell脚本单例运行,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。看起来可行的方法一个非常简单的思路就是,新的脚本被执行时,先检测当前脚本是否有其他实例正在运行...
    99+
    2023-06-16
  • linux如何运行shell脚本
    要运行一个Shell脚本,可以使用以下方法:1. 在终端中直接键入脚本的路径和名称,例如:```/path/to/script.sh...
    99+
    2023-08-30
    linux shell
  • 如何实现Shell菜单脚本
    这篇文章将为大家详细讲解有关如何实现Shell菜单脚本,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。编写的Shell菜单脚本,傻瓜式的人机交互,人人都可以操作linux。#!/bin/sh#Shell菜单...
    99+
    2023-06-09
  • Shell脚本实现检测进程是否正在运行
    这里简单介绍一个自己写的检测某个进程是否存在的bash小脚本。直接上代码。 #!/bin/bash ps_out=`ps -ef | grep $1 | grep -v 'grep' | grep -v...
    99+
    2022-06-04
    脚本 正在运行 进程
  • shell脚本实现多进程运行的方法示例
    本文主要跟大家分享了shell脚本实现多进程运行的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 例子 for ip in 192.168.56.{1..254} do ( ping ...
    99+
    2022-06-04
    示例 脚本 进程
  • Linux 查询正在运行的shell脚本命令
    查看当前运行的所有进程。 ps -A 如果太多了找不到,看的眼花,可以加条件 grep是分组 查看正在运行的shell脚本的进程shell脚本就是 sh ps -ef |grep  sh 如图下面就是查询出来的所有sh脚本,看第...
    99+
    2023-09-03
    linux 运维 服务器
  • Shell脚本运行中的停止方法实现
    linux系统Shell中提交了一个脚本,但是需要停止这个进程,如何处理? 方式1 killall file-flume-kafka 说明:killall是一个命令,不是kill all,file-flume-kafka...
    99+
    2022-06-04
    Shell脚本运行停止 Shell脚本停止
  • 如何实现Linux Shell脚本数学运算
    本篇内容介绍了“如何实现Linux Shell脚本数学运算”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在任何一种编程语言中,算术运算都是必...
    99+
    2023-06-09
  • Shell脚本实现监控iptables运行状态
    最近在调试服务器的iptables,自己做了个定时关iptables,但晚上回家很少开电脑,所以就没法去启动iptables,当然你可能会说,为什么不取消定时关闭iptables,我只能说个人的环境不一样,...
    99+
    2022-06-04
    脚本 运行状态 Shell
  • 如何在 Linux 中运行一个 Shell 脚本
    本篇内容介绍了“如何在 Linux 中运行一个 Shell 脚本”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在 Linux 中有两种运行 ...
    99+
    2023-06-15
  • 如何用shell脚本实现监控shell脚本的执行流程及变量的值
    本篇内容主要讲解“如何用shell脚本实现监控shell脚本的执行流程及变量的值”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何用shell脚本实现监控shell脚本的执行流程及变量的值”吧!...
    99+
    2023-06-09
  • 使用shell脚本怎么实现多进程运行
    这篇文章将为大家详细讲解有关使用shell脚本怎么实现多进程运行,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。例子for ip in 192.168.56.{1...
    99+
    2023-06-09
  • 如何实现Shell脚本逐行读取文本文件
    这篇文章主要介绍“如何实现Shell脚本逐行读取文本文件”,在日常操作中,相信很多人在如何实现Shell脚本逐行读取文本文件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何实现Shell脚本逐行读取文本文件...
    99+
    2023-06-09
  • Shell脚本实现监视指定进程的运行状态
    在之前的博客中,曾经写了自动化测试程序的实现方法,现在开发者需要知道被测试的进程(在此指运行在LINUX上的主进程的)在异常退出之前的进程的运行状态,例如内存的使用率、CPU的使用率等。 现用shell脚本...
    99+
    2022-06-04
    脚本 运行状态 进程
  • Shell脚本注释如何实现
    这篇文章主要介绍了Shell脚本注释如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Shell脚本注释如何实现文章都会有所收获,下面我们一起来看看吧。单行注释直接在行最前端加上符号 # 即可。具体用法如下...
    99+
    2023-07-05
  • linux如何实现监视端口是否正常的shell脚本
    这篇文章将为大家详细讲解有关linux如何实现监视端口是否正常的shell脚本,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。代码如下:#!/bin/bash port=”80″ res...
    99+
    2023-06-09
  • linux中shell脚本编写和运行的示例分析
    这篇文章主要介绍了linux中shell脚本编写和运行的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。编写第一个shell脚本在gedit中编写.sh格式的文件,保存...
    99+
    2023-06-09
  • Shell脚本如何实现文本处理
    这篇文章给大家分享的是有关Shell脚本如何实现文本处理的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。4.1 排序文本4.1.1 行的排序未提供命令行选项时,整个记录会根据当前locale所定义的次序排序。在传统...
    99+
    2023-06-09
  • 如何监控docker容器运行状态 shell 脚本
    场景 公司项目部署在docker中,由于未知原因容器偶尔会停止,需要写一个脚本监控 容器运行状态,如果容器停止了,就再启动该容器 shell脚本 #!/bin/bash # 传入...
    99+
    2024-04-02
  • shell之正向解析脚本的实现方法
    正向解析脚本 #!/bin/bash yum install bind -y //安装解析工具包 //修改主配置文件 sed -i '13s/127.0.0.1/192.168.17.156/' /etc/n...
    99+
    2022-06-04
    shell 正向解析脚本 shell 正向解析shell脚本
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作