在基于 Debian 的系统上,我有一个每 30 分钟运行一次的计划作业(例如 cron 作业或 systemd 计时器/服务)。但是,我不希望在安装或更新软件包的同时发生这种情况。
软件包安装可以手动或按计划进行,但在后一种情况下,会出现相当大的随机延迟。我可以调整我的工作时间表,以免干扰潜在的软件包更新(无论是否实际安装了某些内容),并记住在手动安装软件包时禁用该作业,并记住在之后启用它 - 但这并不令人满意。
因此,我正在寻找一种可靠的方法来告诉软件包安装正在进行中,以便我的工作可以检查它并退出(或延迟执行)(如果是这种情况)。如果在我的工作的同时在后台更新存储库信息或下载软件包,这并不是真正的问题,但我的工作不应在安装时运行(复制文件、配置、安装前/安装后脚本和相似的)。
在 OPNsense(基于 FreeBSD)上,系统更新程序获取特定文件的锁定,因此我将我的工作封装在flock
.如果正在进行更新,我的工作将被跳过。如果在我的作业运行时触发升级,升级可能会失败,并显示一条消息,指示另一个更新正在进行中。
我想知道 Debian 上的 apt 是否有类似的东西,例如我可以检查的锁定文件。如果是这样,该机制是特定包管理前端独有的,还是可以与 .deb 包的所有标准工具(例如 dpkg、apt、aptitude、synaptic 等)一起使用?
我看到当 Synaptic 打开并尝试运行时sudo apt-get upgrade
,我得到:
E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 1234 (synaptic)
N: Be aware that removing the lock file is not a solution and may break your system.
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
然而,即使 Synaptic 正在运行(尽管当前没有安装任何东西),sudo flock -n /var/lib/dpkg/lock-frontend sleep 10 || echo File is locked
也会成功(即flock
返回true
,表明我已经获得了锁,而没有获得锁sleep
则执行)。echo
与 相同的行为/var/lib/dpkg/lock
。
那么如何才能获得“包安装锁定”呢?
Debian 上的包管理器 – 从我的测试结果来看,这对于
apt
前端来说也是如此dpkg
– 锁定两个文件,/var/lib/dpkg/lock
以及/var/lib/dpkg/lock-frontend
.根据我的测试,一旦 GUI 出现,Synaptic 就会锁定这两个文件,并保留它们直到它退出。然而,Linux上有不同种类的锁,并且不能保证彼此兼容,因此两种方法可能会同时获取同一个文件的排他锁:
flock(1)
,内部调用flock(2)
,以及lockf(3)
fcntl(2)
,内部调用正如这个答案中详细介绍的,
dpkg
使用并且一直fcntl(2)
在内部使用。不幸的是,虽然flock(2)
大多数 Debian 系统都提供了一个命令行包装器,但我还没有找到fcntl(2)
.您的选择是安装chiark-utils-bin
(它会为您提供with-lock-ex(1)
)或编写一些 Python 代码。以下内容对我有用,在 Synaptic 运行时报告文件已锁定,但在没有 apt 工具运行时报告成功:经过测试,我可以确认这会阻止相关 Python 程序和包管理器的并发执行——无论谁先尝试获取锁,其他进程都必须稍后重试。 Software Updater 显示
Waiting for python3 to finish
Python 程序是否持有锁;如果 Synaptic 正在运行或更新管理器正在安装更新,Python 程序将显示错误消息。不需要显式释放锁——当持有锁的进程退出时,这会自动发生。