我正在尝试创建一个安装自定义键盘布局的 Debian 软件包。为此,您需要修改 中的两个文件/usr/share/X11/xkb
。因此,我的软件包仅包含这些文件的新版本。当我尝试安装它时,dpkg 抱怨与 xkeyboard 软件包冲突,不让我安装。我知道--force-overwrite
无论如何我都可以使用它来安装它,但我担心以后会卸载该软件包。我想创建一个具有以下行为的 Debian 软件包:
- 安装时,覆盖属于其他包的文件。
- 卸载时,文件将返回到安装之前的状态。
这可能吗?
答案1
可以让 dpkg 在重新安装其所属的软件包时不覆盖文件,而是将软件包中的文件放到其他地方。
这可以在本地使用来覆盖包中的文件版本,或者由一个包覆盖另一个包的版本(或为其提供包装器)。
有一个转移列表,它由 dpkg 读取,并由特殊程序 dpkg-divert 更新。请参阅 dpkg-divert(8) 了解其操作的完整细节。
当一个软件包希望从另一个软件包转移文件时,它应该在其预安装中调用 dpkg-divert 来添加转移并重命名现有文件。例如,假设 smailwrapper 软件包希望在 /usr/sbin/smail 周围安装包装器:
dpkg-divert --package smailwrapper --add --rename \
--divert /usr/sbin/smail.real /usr/sbin/smail
--package smailwrapper 确保 smailwrapper 的 /usr/sbin/smail 副本可以绕过转移并安装为真实版本。在升级时无条件添加转移是安全的,因为如果已经存在,它将保持不变,但 dpkg-divert 将显示一条消息。要隐藏该消息,请使命令以要升级的软件包的版本为条件:
if [ upgrade != "$1 || dpkg --compare-versions "$2" lt 1.0-2; then
dpkg-divert --package smailwrapper --add --rename \
--divert /usr/sbin/smail.real /usr/sbin/smail
fi
其中 1.0-2 是首次将转移添加到软件包的版本。在中止升级期间运行该命令毫无意义,但无害。
postrm 必须做相反的事情:
if [ remove = "$1" -o abort-install = "$1" -o disappear = "$1; then
dpkg-divert --package smailwrapper --remove --rename \
--divert /usr/sbin/smail.real /usr/sbin/smail
fi
如果在特定版本中添加了转移,则 postrm 还应处理从旧版本升级失败的情况(除非旧版本太旧而不再支持直接升级):
if [ abort-upgrade = "$1 && dpkg --compare-versions "$2" lt 1.0-2; then
dpkg-divert --package smailwrapper --remove --rename \
--divert /usr/sbin/smail.real /usr/sbin/smail
fi
其中 1.0-2 是首次将转移添加到软件包的版本。postrm 不应在升级时删除转移,因为没有理由只删除转移然后立即重新添加它,并且由于旧软件包的 postrm 是在解压后运行的,因此删除转移将失败。
不要尝试转移对于系统运行至关重要的文件 - 当使用 dpkg-divert 时,在转移之后但在 dpkg 安装新版本之前,该文件可能不存在。
不要尝试转移 conffile,因为 dpkg 不能很好地处理它。
从 debian wiki 复制粘贴:https://www.debian.org/doc/debian-policy/ap-pkg-diversions.html