flock 命令详解
更新时间:2026-09-17。「一个命令一个文档」系列,属于日志与计划任务族。最经典用途:防止 crontab 任务上一轮没跑完、下一轮又启动导致重叠。
flock 对一个锁文件加建议性锁(advisory lock)。拿不到锁说明已有实例在跑。锁绑定在打开的文件描述符上,进程退出(哪怕崩溃)内核自动释放,不会像 pidfile 那样残留死锁。
一、两种用法
bash
# 1) 命令式:flock 加锁后执行命令,命令结束释放
flock -n /tmp/job.lock -c '/opt/sync.sh'
# 2) 文件描述符式(脚本内临界区,最推荐)
(
flock -n 9 || exit 1
# ...只有拿到锁才执行的临界区...
) 9>/var/lock/myjob.lock二、常用选项
| 选项 | 含义 |
|---|---|
-x/--exclusive | 独占锁(默认) |
-s/--shared | 共享锁(多读单写场景) |
-n/--nonblock | 拿不到立即失败返回,不等待(防 cron 重叠必用) |
-w N | 等待 N 秒仍拿不到就放弃 |
-E CODE | 拿不到锁时的退出码(默认 1) |
-u | 提前解锁(少用,一般靠退出自动释放) |
三、crontab 防重入(头号场景)
cron
# 每 5 分钟跑一次,但若上一轮没结束则本轮直接跳过,绝不重叠
*/5 * * * * /usr/bin/flock -n /var/lock/backup.lock /opt/backup.sh >>/var/log/backup.log 2>&1不加 flock 时,任务耗时 > 调度间隔就会多实例并发跑:可能造成重复写库、重复扣款、互踩临时文件。
-n让新实例立刻退出(而不是排队等,排队反而会在恢复后堆积一串)。需要"恰好串行不丢轮次"才用-w等待。
四、单实例守护与注意
- 锁文件本身一般提前
touch或让 flock 用重定向9>file创建即可;文件内容无关紧要。 - 崩溃安全:持锁进程被杀/掉电,FD 关闭,锁自动释放——这是 flock 优于手写 pidfile 判断的地方(pid 可能被复用)。
- 建议性锁:只有协作的进程都用 flock 才互斥;不检查锁的程序照样能读写文件,它不是访问控制。
- 锁文件放本地磁盘。NFS 上 flock 语义依赖 NFS 版本与挂载选项(
nolock会让它失效),跨机锁要用 NFSv4 lease 或专用分布式锁。 - 父进程加锁后
&后台子进程默认继承 FD,会导致锁在子进程上仍持有;脚本里注意 FD 生命周期。
相关命令
定时调度见 crontab 与crontab 不执行 FAQ,进程互斥排查用 ps/pgrep,分布式多机互斥另需 Redis/ZooKeeper 锁而非单机 flock。
总结
flock 用文件描述符上的建议性锁实现进程互斥:flock -n lockfile -c 'cmd' 拿不到锁立即退出,是 crontab 防任务重叠、单实例守护的标准做法;锁随进程退出(含崩溃)由内核自动释放、无 pidfile 残留问题;但它只在"都用 flock 的协作进程"间生效、属建议锁,且应放本地盘、慎用 NFS,跨机互斥要用分布式锁。