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就是你需要的休眠时长,后面的代码块替换成你实际要执行的业务命令即可。
使用步骤
- 将代码保存为
my_script.sh - 给脚本添加执行权限:
chmod +x my_script.sh - 在一个终端运行:
./my_script.sh - 立刻在另一个终端再次运行,会收到错误提示,无法启动新实例
注意事项
- PID文件路径可自定义:如果脚本需要长期运行,可将PID文件放在
/var/run目录(需要root权限),普通场景用/tmp足够。 - 避免PID文件冲突:如果你的脚本名称比较通用,建议给PID文件加独特前缀(比如
/tmp/my_app_unique_script.pid),防止和其他进程的PID文件重名。
内容的提问来源于stack exchange,提问作者Nik




