小编han*_*nno的帖子

Linux 中陈旧文件锁的处理和 flock 的稳健使用

我有一个定期通过 cron 执行的脚本(每隔几分钟)。然而,脚本不应并行运行多次,有时运行时间会更长,因此我想实现一些锁定,即如果前一个实例已经在运行,请确保脚本提前终止。

根据各种建议,我有一个看起来像这样的锁定:

lock="/run/$(basename "$0").lock"
exec {fd}<>"$lock"
flock -n $fd || exit 1
Run Code Online (Sandbox Code Playgroud)

这应该调用 exit 1 以防脚本的另一个实例仍在运行。

现在问题来了:似乎有时即使脚本已经终止,陈旧的锁仍然存在。这实际上意味着 cron 永远不会再次执行(直到下次重新启动或删除锁定的文件),这当然不是我想要的。

我发现有列出现有文件锁的 lslocks 命令。它显示了这一点:

(unknown)        2732 FLOCK        WRITE 0     0   0 /run...                                                                 
Run Code Online (Sandbox Code Playgroud)

进程(在这种情况下为 2732)不再存在(例如在 ps aux 中)。我也不清楚为什么它不显示完整的文件名(即只有 /run...)。lslocks 有一个参数 --notrucate 在我看来它可能会避免截断文件名,但这不会改变输出,它仍然是 /run...

所以我有多个问题:

  • 为什么会有这些锁,什么情况会导致 flock 的锁存在于进程的生命周期之外?
  • 为什么 lslocks 不显示完整路径/文件名?
  • 什么是避免这种情况并使脚本中的锁定更健壮的好方法?
  • 有没有办法在不重新启动的情况下清理陈旧的锁?

shell-script lock flock

4
推荐指数
1
解决办法
1433
查看次数

标签 统计

flock ×1

lock ×1

shell-script ×1