最简单可靠的方式是在crontab中用flock -xn包裹命令:-x加独占锁,-n非阻塞抢锁失败即跳过,-c后接带引号的完整命令,锁文件用绝对路径如/var/run/myjob.lock。

直接在 crontab 里用 flock 包裹命令,是最简单、最可靠的方式。核心是让每次调度尝试先抢一个独占锁,抢不到就跳过,不堆积、不并发。
用 flock 命令包裹脚本调用
在 crontab 中不要直接写脚本路径,而是加上 flock -xn 命令:
-
-x表示加独占锁(同一时间只允许一个实例) -
-n表示非阻塞——抢不到锁立刻退出,不等待 -
-c后面跟完整命令,注意用单引号或双引号包住整个命令串 - 锁文件建议用绝对路径,如
/tmp/myjob.lock或/var/run/myjob.lock
示例(每分钟执行一次,但脚本可能跑 5 分钟):
* * * * * flock -xn /tmp/backup.lock -c '/usr/local/bin/backup.sh >> /var/log/backup.log 2>&1'
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
锁文件位置要注意的细节
锁文件不能放在会被自动清理的地方,否则可能导致误判:
-
/tmp/下的文件可能被系统定期清空(尤其使用 tmpfs 的发行版),建议改用/var/run/或项目目录下的固定路径 - flock 会自动创建并管理
配合日志和反馈更安心
加个简单判断,让失败时也能留下痕迹:
- 在命令末尾加
|| echo "$(date): skipped — already running" >> /var/log/myjob.log - 这样即使跳过执行,也能从日志看出“不是没触发,而是被锁拦住了”
- 避免误以为 cron 没生效,反复排查调度配置
不推荐的做法
有些方案看似可行,但实际容易出问题:
- 在脚本内部自己 touch/rm 锁文件:异常退出时锁残留,导致后续永远无法执行
- 用
pgrep检查进程名:存在极短时间窗口的竞态,且命令行参数变化时匹配失效 - 依赖
sleep或重试逻辑:会让任务堆积,占用更多资源,违背防重初衷

















