You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Linux下实现Shell脚本单实例运行的方法及代码示例

没问题,我来给你搞定这个需求——核心就是用PID文件来跟踪正在运行的进程,避免重复启动。下面是完整的示例脚本,我会一步步给你讲清楚每个部分的作用:

单实例休眠执行的Shell脚本实现

先看完整的可直接运行的代码,之后我拆解关键逻辑:

#!/bin/bash

# 定义PID文件路径,建议放在/tmp目录(临时文件区),也可自定义到脚本所在目录
PID_FILE="/tmp/my_single_instance_script.pid"

# 第一步:检查是否已有同脚本进程在运行
if [ -f "$PID_FILE" ]; then
    # 读取PID文件中记录的进程ID
    EXISTING_PID=$(cat "$PID_FILE")
    # 验证该PID对应的进程是否真的存活(防止脚本异常退出导致PID文件残留)
    if ps -p "$EXISTING_PID" > /dev/null 2>&1; then
        echo "错误:脚本已在运行,进程ID为 $EXISTING_PID,无法启动新实例。"
        exit 1
    else
        # 若PID文件存在但进程已结束,清理残留文件
        echo "发现残留的PID文件,已自动清理。"
        rm "$PID_FILE"
    fi
fi

# 第二步:将当前脚本的PID写入PID文件
echo $$ > "$PID_FILE"

# 第三步:核心业务逻辑——先休眠指定时间,再执行任务
echo "脚本启动,进程ID为 $$,将在20秒后执行任务..."
sleep 20

# 替换成你实际要执行的命令,比如你提到的测试内容
echo "this is a process"
# 示例:操作testfile(根据你的需求调整)
# touch testfile
# echo "任务执行结果" > testfile

# 第四步:脚本正常结束后,删除PID文件
rm "$PID_FILE"

# 额外防护:捕获中断/终止信号(如Ctrl+C、系统kill命令),确保PID文件被清理
trap 'rm -f "$PID_FILE"; exit 1' INT TERM EXIT

关键逻辑拆解

  • PID文件的核心作用:用一个文件记录当前运行脚本的进程ID,每次启动前先检查这个文件,判断是否有活跃的同脚本进程。
  • 进程存活验证ps -p "$EXISTING_PID" > /dev/null 2>&1 是为了避免脚本异常崩溃后,PID文件残留导致后续无法启动的问题——只有当PID对应的进程真的在运行时,才阻止新实例启动。
  • 陷阱(trap)处理:添加trap命令是为了应对用户手动终止脚本(比如Ctrl+C)或脚本被系统信号终止的场景,确保无论脚本如何退出,PID文件都会被清理。
  • 休眠与任务sleep 20就是你需要的休眠时长,后面的代码块替换成你实际要执行的业务命令即可。

使用步骤

  1. 将代码保存为my_script.sh
  2. 给脚本添加执行权限:chmod +x my_script.sh
  3. 在一个终端运行:./my_script.sh
  4. 立刻在另一个终端再次运行,会收到错误提示,无法启动新实例

注意事项

  • PID文件路径可自定义:如果脚本需要长期运行,可将PID文件放在/var/run目录(需要root权限),普通场景用/tmp足够。
  • 避免PID文件冲突:如果你的脚本名称比较通用,建议给PID文件加独特前缀(比如/tmp/my_app_unique_script.pid),防止和其他进程的PID文件重名。

内容的提问来源于stack exchange,提问作者Nik

火山引擎 最新活动