我已经使用预安装脚本构建了一个 deb 包。我想在安装后自动备份 deb 包。所以我想在安装前/安装后脚本中获取包的完整路径。有什么解决办法吗?
答案1
维护者脚本(preinst
等postinst
)会获得许多信息,但不包括安装它们的包文件的完整路径 - 特别是因为什么时候它们运行时,包文件可能不再存在。
看“内部环境”部分man dpkg
有关可用信息的详细信息,请参见提供给脚本的参数。要了解可以调用维护者脚本的各种情况,请参阅Debian 政策中的维护者脚本流程图附录;特别注意,即使是旧的preinst
脚本也postinst
可以被调用,它们不仅在安装包含它们的包时有用。
您也许可以通过使用dpkg
钩子(特别是post-invoke
由 触发的钩子)来完成您想要的操作install
。
答案2
文件的作者deb
不应有权决定用户如何归档其包。当你的时候dpkg -i mypkg.deb
,mypkg.deb
是不会被删除的。作为用户,您可以选择是否自行存档该包。
如果您通过 apt 安装软件包apt
,软件包会自动归档/var/cache/apt/archives
。用户可以在 中禁用此功能apt.conf
。该控制对于所有包都是全局的,而不是基于每个包。
从中提取的包的名称deb
不会作为参数传递给preinst
.因此,您不能简单地:
cp "$2" /var/cache/apt/archives/
另外, 的工作目录preinst
是/
.因此,即使您假设用户没有重命名该包,您仍然无法执行此操作:
cp mypkg.deb /var/cache/apt/archives/
我认为您能做的最接近的事情就是使用该dpkg-repack
工具。这不是标准工具的一部分,需要通过安装apt install dpkg-repack
。因此,如果您使用它,它应该是您的包的依赖项。
man dpkg-repack
说:
dpkg-repack
从系统上已安装的 Debian 软件包创建一个 .deb 文件。如果在解压包时对包进行了任何更改(例如/etc
修改了conffiles 文件),则新包将继承这些更改。 (也有例外情况,包括对非配置文件的配置文件的更改,包括由 管理的配置文件ucf(1)
。)
由于这仅适用于已安装的软件包,因此您需要将其从 移至preinst
的末尾postinst
。
dpkg-repack mypkg
mv mypkg_1.0-1_all.deb /var/cache/apt/archives/
请注意,我最多将其标记为“易失性”。我不建议这样做,除非这个包不打算发布。如果您只是希望能够恢复您自己的个人设置并将其应用到您的下一台计算机,并且您只是想要一种简单的方法来存档您的包,那么它可能没问题。但请考虑一下,简单的方法echo "Don't forget to archive me!"
也可能有效。
上述想法的更好替代方法是创建一个本地apt
存储库。将此包放入该存储库中,将本地存储库添加到您的sources.list
,然后apt install mypkg
而不是dpkg -i mypkg.deb
.然后apt
将使用您的全局策略来确定如何存档mypkg.deb
。
这样做的另一个好处是,不会强制您可能与之共享的任何其他用户对该包进行存档。
创建本地存储库有几种方法apt
:
dpkg-scanpackages
:https://help.ubuntu.com/community/Repositories/Personalreprepro
:有点复杂,但是如果您正在管理共享存储库,那么它确实很好,特别是如果您包含源代码并且需要使用存储库签名来签署内容。
答案3
冒着被否决的风险,这是可以做到的。如果从脚本中获取父进程的信息preinst
,就可以获取包的路径。您需要两条信息:
- 父进程的工作目录
- 父进程的最后一个参数(dpkg/apt 内部调用 dpkg-deb,所有选项之后的最后一个参数是完整的包名称)
实际上,这看起来像:
CALLING_DIR=$(realpath /proc/$(ps -o ppid:1= $$)/cwd)
DEBIAN_PKG=$(cd "${CALLING_DIR}"; realpath $(xargs -0 -n 1 < /proc/$(ps -o ppid:1= $$)/cmdline | tail -n 1))
echo "${DEBIAN_PKG}"
正如其他答案所指出的,这是极不寻常需要这些信息。我能想到这样做的唯一原因(我现在正在玩的)是如果您的包生成需要包含包本身的可再发行组件。除此之外,最好安装一个挂钩。