为什么使用flock后apt也不会显示错误信息呢?

为什么使用flock后apt也不会显示错误信息呢?

运行脚本

#!/bin/bash
(
 flock 9 
  # ... commands executed under lock ...
 fuser -v /var/lib/dpkg/lock
 apt-get -f --assume-no install
) 9>/var/lib/dpkg/lock

作为超级用户不会显示错误信息。但是如果有 egsynaptic正在运行,apt-get则会显示错误信息:“E: 无法获取锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用)”。

答案1

dpkg(反过来 apt)不用于flock(2)锁定。检查所涉及的系统调用,似乎它们使用fcntl(2)

$ sudo strace -f -e trace=desc apt install foo |& grep -B2 F_SETLK
close(4)                                = 0
open("/var/lib/dpkg/lock", O_RDWR|O_CREAT|O_NOFOLLOW, 0640) = 4
fcntl(4, F_SETFD, FD_CLOEXEC)           = 0
fcntl(4, F_SETLK, {l_type=F_WRLCK, l_whence=SEEK_SET, l_start=0, l_len=0}) = -1 EAGAIN (Resource temporarily unavailable)
close(4)                                = 0

来自这篇文章

在 Linux 中,lockf()只是 的包装器fcntl(),而flock() 锁是分开的(并且只适用于本地文件系统,不适用于 NFS 挂载)。也就是说,一个进程可以 flock()对文件拥有咨询性排他锁,而另一个进程对同一个文件拥有咨询性排他fcntl()锁。两者都是咨询性锁,但它们不会交互。

因此,flock无法有效地将其锁定在其他包管理命令上。(想想看……如果有效的话,那么后续命令apt-get无论如何都会失败。)


/var/lib/dpkg/lock我能想到的最简单的方法是在任务执行期间创建一个不可变的文件。

touch /var/lib/dpkg/lock
chattr +i /var/lib/dpkg/lock

或者您可以编写一个简短的 C 程序(或任何提供简单界面的语言fcntlfcntl来像 dpkg 一样锁定它。

相关内容