4.3. Epoch, Scriptlets 和 Triggers
本节介绍 Epoch
、Scriptlets
和 Triggers
,它们代表 RMP SPEC 文件的高级指令。
所有这些指令都影响不仅影响 SPEC 文件,还影响到安装结果 RPM 的末尾计算机。
4.3.1. Epoch 指令
Epoch
指令支持根据版本号定义权重的依赖关系。
如果 RPM SPEC 文件中未列出此指令,则完全不设置 Epoch
指令。这与常规的理解不同:不设置 Epoch
的结果是 Epoch
为 0。但是,YUM 实用程序将未设置的 Epoch
视为 Epoch
为 0,用于 depsolving。
但是,在 SPEC 文件中列出 Epoch
时通常会被省略,因为在大多数情况下,如果使用 Epoch
值,则在进行软件包版本比较时会 skews 预期的 RPM 行为。
例 4.2. 使用 Epoch
如果您使用 Epoch: 1
和 Version: 1.0
安装 foobar
软件包,其他软件包 foobar
with Version: 2.0
但没有 Epoch
指令,则新版本永远不会被视为更新。原因是,在签发 RPM 软件包版本是首选使用 Epoch
版本而不是传统的 Name-Version-Release
marker。
使用 Epoch
比较罕见。但是,Epoch
通常用于解决升级排序问题。在软件版本号方案或带有字母字符的版本中,这个问题可能会出现上游变化的影响,这些字符不能始终根据编码进行可靠地进行比较。
4.3.2. Scriptlets
Scriptlets 是一组在安装或删除软件包之前或之后执行的 RPM 指令。
使用 Scriptlets 仅在构建时或启动脚本中无法完成的任务。
4.3.2.1. scriptlets 指令
存在一组常用 Scriptlet 指令。它们和 SPEC 文件部分标题类似,如 %build
或 %install
。它们由多行代码段定义,这些片段通常写为标准的 POSIX shell 脚本。但是,它们也可以使用其他适用于目标机器分布接受的 RPM 编程语言编写。RPM 文档包括可用语言的详尽列表。
下表包含 Scriptlet 指令,按其执行顺序列出。请注意,包含脚本的软件包会在 %pre
和 %post
指令之间安装,并在 %preun
和 %postun
指令之间卸载。
指令 | 定义 |
---|---|
| Scriptlet 在安装或删除任何软件包之前执行。 |
| Scriptlet 在目标系统上安装软件包之前执行。 |
| Scriptlet 仅在目标系统上安装软件包后执行。 |
| 在从目标系统卸载软件包前执行的 Scriptlet。 |
| Scriptlet 在软件包从目标系统卸载后执行。 |
| 在事务结束时执行的 Scriptlet。 |
4.3.2.2. 关闭 scriptlet 执行
要关闭任何 scriptlet 的执行,请使用 rpm
命令和 --no_scriptlet_name_
选项。
流程
例如,要关闭
%pretrans
scriptlets 的执行,请运行:# rpm --nopretrans
您还可以使用
-- noscripts
选项,它等同于以下所有:-
--nopre
-
--nopost
-
--nopreun
-
--nopostun
-
--nopretrans
-
--noposttrans
-
其他资源
-
详情请查看
rpm (8)
手册页。
4.3.2.3. scriptlets 宏
Scriptlets 指令也适用于 RPM 宏。
以下示例显示了使用 systemd scriptlet 宏,这样可确保 systemd 会收到有关新单元文件的通知。
$ rpm --showrc | grep systemd -14: transaction_systemd_inhibit %{plugindir}/systemd_inhibit.so -14: _journalcatalogdir /usr/lib/systemd/catalog -14: _presetdir /usr/lib/systemd/system-preset -14: _unitdir /usr/lib/systemd/system -14: _userunitdir /usr/lib/systemd/user /usr/lib/systemd/systemd-binfmt %{?} >/dev/null 2>&1 || : /usr/lib/systemd/systemd-sysctl %{?} >/dev/null 2>&1 || : -14: systemd_post -14: systemd_postun -14: systemd_postun_with_restart -14: systemd_preun -14: systemd_requires Requires(post): systemd Requires(preun): systemd Requires(postun): systemd -14: systemd_user_post %systemd_post --user --global %{?} -14: systemd_user_postun %{nil} -14: systemd_user_postun_with_restart %{nil} -14: systemd_user_preun systemd-sysusers %{?} >/dev/null 2>&1 || : echo %{?} | systemd-sysusers - >/dev/null 2>&1 || : systemd-tmpfiles --create %{?} >/dev/null 2>&1 || : $ rpm --eval %{systemd_post} if [ $1 -eq 1 ] ; then # Initial installation systemctl preset >/dev/null 2>&1 || : fi $ rpm --eval %{systemd_postun} systemctl daemon-reload >/dev/null 2>&1 || : $ rpm --eval %{systemd_preun} if [ $1 -eq 0 ] ; then # Package removal, not upgrade systemctl --no-reload disable > /dev/null 2>&1 || : systemctl stop > /dev/null 2>&1 || : fi
4.3.3. Triggers 指令
Triggers 是 RPM 指令,可提供在软件包安装和卸载期间交互的方法。
Triggers 可能会在意外执行,例如在更新包含软件包时执行。很难调试 Triggers,因此需要以可靠的方式实施它们,以便在意外执行时不会中断任何操作。因此,{RH} 建议最小化 Triggers 的使用。
下面列出了执行顺序以及每个现有 Triggers 的详情:
all-%pretrans … any-%triggerprein (%triggerprein from other packages set off by new install) new-%triggerprein new-%pre for new version of package being installed … (all new files are installed) new-%post for new version of package being installed any-%triggerin (%triggerin from other packages set off by new install) new-%triggerin old-%triggerun any-%triggerun (%triggerun from other packages set off by old uninstall) old-%preun for old version of package being removed … (all old files are removed) old-%postun for old version of package being removed old-%triggerpostun any-%triggerpostun (%triggerpostun from other packages set off by old un install) … all-%posttrans
以上项目位于 /usr/share/doc/rpm-4.*/triggers
文件中。
4.3.4. 在 SPEC 文件中使用非 shell 脚本
SPEC 文件中的 -p
scriptlet 选项允许用户调用特定的解释器,而不是默认的 shell 脚本解释器(-p /bin/sh
)。
下面的步骤描述了如何创建脚本,它会在安装 pello.py
程序后输出信息:
步骤
-
打开
pello.spec
文件。 找到以下行:
install -m 0644 %{name}.py* %{buildroot}/usr/lib/%{name}/
在上面的行下,插入:
%post -p /usr/bin/python3 print("This is {} code".format("python"))
安装软件包:
# yum install /home/<username>/rpmbuild/RPMS/noarch/pello-0.1.2-1.el8.noarch.rpm
安装后检查输出信息:
Installing : pello-0.1.2-1.el8.noarch 1/1 Running scriptlet: pello-0.1.2-1.el8.noarch 1/1 This is python code
要使用 Python 3 脚本,在 SPEC 文件中的 install -m
下包含以下行:
%post -p /usr/bin/python3
要使用 Lua 脚本,在 SPEC 文件中的 install -m
下包含以下行:
%post -p <lua>
这样,您可以在 SPEC 文件中指定任何解释器。