可靠单例需结合锁文件与进程存活检测:写入pid到锁文件,启动时用kill -0校验pid对应进程是否运行,配合trap自动清理;或直接使用flock -n实现更轻量可靠的文件锁。

直接用文件存在性判断实现单例运行看似简单,但容易出问题——比如进程异常退出后锁文件残留,导致后续脚本永远无法启动。所以不能只看“文件是否存在”,必须结合进程有效性验证。
核心思路:锁文件 + 进程存活检测
真正可靠的方案是:创建一个锁文件,里面写入当前脚本的 PID;每次启动时先检查该文件是否存在,若存在,再确认里面记录的 PID 对应的进程是否仍在运行。只有两者都满足,才拒绝启动。
- 锁文件路径建议用 /tmp/脚本名.lock 或 /var/run/脚本名.pid,确保全局可写且不易冲突
- 用 kill -0 $PID 检查进程是否存活(不发信号,只做权限和存在性校验)
- 用 trap 保证脚本退出时自动清理锁文件,覆盖正常退出和多数异常退出场景
完整 shell 脚本示例
以下是一个健壮可用的单例 shell 脚本模板:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
#!/bin/bash LOCKFILE="/tmp/myscript.lock" <h1>检查锁文件是否存在且对应进程在运行</h1><p>if [[ -f "$LOCKFILE" ]] && kill -0 "$(cat "$LOCKFILE" 2>/dev/null)" 2>/dev/null; then echo "$0 already running." >&2 exit 1 fi</p><h1>写入当前 PID 并设置退出清理</h1><p>echo $$ > "$LOCKFILE" trap 'rm -f "$LOCKFILE"' EXIT</p><h1>此处放你的主逻辑</h1><p>echo "Script started with PID $$" sleep 10 </p>
为什么不能只用 [ -e lockfile ]?
单独判断文件存在会误判:
- 脚本上次崩溃或被 kill -9 终止,锁文件没删掉,新实例就卡死
- 多个用户运行同名脚本,PID 冲突或权限混乱,导致误杀或漏检
- 文件系统挂载异常、NFS 延迟等边界情况让 -e 返回不可靠结果
更轻量替代方案:用 flock 命令
如果系统有 flock(绝大多数 Linux 发行版默认自带),推荐用它代替手写锁逻辑:
#!/bin/bash exec flock -n /tmp/myscript.lock -c ' # 这里是你的实际脚本内容 echo "Running at $(date)" sleep 10 '
参数说明:-n 表示非阻塞,获取不到锁立即失败;exec 确保 flock 生命周期与脚本一致;锁在进程退出时由内核自动释放,无需手动清理。










