flock 的等待与超时模式
flock 用文件锁保证同一任务不并发执行:默认会一直阻塞等待,加 -w 秒 限定最长等待时间,加 -n 则立即失败返回。配合 -E 还能自定义「拿不到锁」时的退出码,于是监控就能区分「这次被跳过」与「脚本本身失败」。定时任务加锁时选等待还是跳过,取决于业务语义。
基本信息
| 用途 | 防止同一任务并发执行 |
|---|---|
| 语法 | flock [-n | -w 秒] [-E 退出码] 锁文件 命令 |
| 默认行为 | 阻塞等待直到拿到锁 |
| 退出码 | -E 可自定义拿锁失败的返回码,便于监控识别 |
典型使用场景
- 备份任务限制同时只跑一个实例,避免磁盘争抢
- 报告生成类任务:上一轮没跑完就跳过本轮
- 需要等前一轮收尾的分钟级任务,用限时等待
- 监控需要区分「跳过」与「失败」时自定义退出码
- 手工触发与定时触发并存时防止互相踩
- 脚本编排里串行化访问同一份资源
常用示例
常用示例
flock -w 300 -E 75 /var/lock/report.lock /opt/report.sh # 最多等 300 秒
flock -n /var/lock/report.lock /opt/report.sh || echo "skip: busy" >> /var/log/report.log
flock -n /var/lock/sync.lock -c 'rsync -a /data/ /backup/' # -c 直接接命令
flock /var/lock/serial.lock -c 'sleep 10' # 无超时:一直等
echo $? # 0 为正常执行,其它看约定
ls -l /var/lock/report.lock # 锁文件只是承载对象,无特殊内容策略选择
| 写法 | 行为 | 适用任务 |
|---|---|---|
| 无参数 | 一直阻塞等待 | 必须完成的串行任务 |
| -w 秒 | 限时等待,超时失败 | 容忍前一实例收尾的任务 |
| -n | 立即失败返回 | 秒级高频、可跳过本次 |
| -E 码 | 自定义拿锁失败退出码 | 监控需区分跳过与失败 |
| -c 命令 | 把命令作为字符串传入 | 简单单行命令更省事 |
备份类任务适合短时等待,容忍前一实例收尾;秒级高频任务适合直接跳过,避免等待队列不断堆积。
-E 会占用一个退出码:脚本自身的退出码可能因此被掩盖,监控对账前要把约定写清楚,否则失败会被当成跳过放过。
锁文件本身没有特殊结构,它只是 flock 的载体。不要手工删除正在使用的锁文件,那样并不会释放锁,反而可能让新实例误以为可以进入。