Bash 脚本是否可以锁定包管理,以便脚本仍然可以使用 apt(和 dpkg)进行更改?

Bash 脚本是否可以锁定包管理,以便脚本仍然可以使用 apt(和 dpkg)进行更改?

我想做这样的事情:

  1. 询问用户要交互删除哪些包
  2. 删除请求的包

并且我想在获取用户输入的同时保持包系统完好无损。

当其他程序正在更改包管理系统中的某些内容时等待,与当我的程序正在决定如何处理包管理系统以及执行决定的操作时防止其他程序开始干扰包管理系统是不同的事情。

查看相关内容错误报告并在那里发表评论。

目前至少有两个用于锁定 dpkg 系统的锁定文件:'/var/lib/dpkg/lock' 和 '/var/lib/dpkg/lock-frontend'。我尝试使用前一个文件通过以超级用户身份启动以下脚本来锁定:

#!/bin/bash
exec {var}>/var/lib/dpkg/lock
flock -n $var || { echo was locked already; exit 1; }
read -p 'Now the lock should be active. Press enter to release.'
exit

但是我仍然可以使用例如sudo apt install,因此apt不认为文件已被锁定。

答案1

flock(1) 管理 flock(2) 锁,而 dpkg 和 apt 使用 fcntl(2) 锁。这两种类型的锁在 Linux 上是完全独立的。

我不知道有任何 shell 工具可以做到正确的锁类型。

要执行您想要的操作,请使用 python3-apt 编写 Python 脚本。这允许您在整个操作过程中保持前端锁定,确保一切正常运行。

没有办法从 shell 正确执行此操作,因为我们还不允许 apt(1) 及其同类的调用者持有前端锁。允许这样做可能也是合理的。

答案2

您可以尝试构建一个拦截器。将apt二进制文件移动到另一个位置(用于which apt找出它的位置)。将其重命名为类似 的名称apt-old,然后以 root 身份在您最初所在的位置创建一个 shell 脚本apt,使其可执行,并使其看起来像这样:

apt-old $@

它将自动将您提供给拦截器脚本的所有参数传递给原始apt二进制文件,这意味着您可以在该行之前放置任何您喜欢的内容,并且它会在每次运行时执行它,例如您可以添加自己的文件锁检查:

#!/usr/bin/bash
if [ -f "/var/file_lock" ]; then
  echo "A program has superior rights to apt at this time."
  exit 1
else
  apt-old $@
fi

这将允许您让程序apt调用不同的文件检查,以检查由您的程序创建的文件。这样您就可以自由地在任何地方和任何时间创建它,同时仍然可以使用 apt 自己的文件锁定机制。

请注意,这不会禁用原始的 apt 二进制文件,您只是移动它以便您的脚本在路径中占据其位置。

相关内容