如何在RPM spec脚本段中判断安装/卸载阶段?
检测RPM脚本段执行阶段的实现方案
核心思路
利用RPM内置宏直接获取当前执行的脚本段名称,通过字符串匹配区分安装/卸载阶段,无需依赖$1/$2的复杂判断,且仅需在SPEC顶部定义一次,无需修改每个脚本段内容。
宏实现方案(推荐)
在SPEC文件顶部添加以下宏定义:
# 定义阶段检测宏 %define detect_stage() \ %global current_section %{__spec_script_section} \ %global is_install 0 \ %global is_uninstall 0 \ %if "%{current_section}" == "%pre" || "%{current_section}" == "%post" || "%{current_section}" == "%triggerin" \ %global is_install 1 \ %elif "%{current_section}" == "%preun" || "%{current_section}" == "%postun" || "%{current_section}" == "%triggerun" \ %global is_uninstall 1 \ %endif
在需要区分阶段的脚本段开头调用宏,后续直接用变量判断逻辑:
%pre %detect_stage if [ %{is_install} -eq 1 ]; then echo "执行安装前逻辑" fi %postun %detect_stage if [ %{is_uninstall} -eq 1 ]; then echo "执行卸载后逻辑" fi %triggerin -- packageA %detect_stage if [ %{is_install} -eq 1 ]; then echo "执行触发安装逻辑" fi
纯Bash实现方案
若不想依赖RPM宏,可在SPEC顶部定义Bash函数,通过解析$0的特殊值判断:
%global setup_stage_detection() \ stage_detect() { \ local script_name=$(basename "$0") \ case "$script_name" in \ pre|post|triggerin) export STAGE=install ;; \ preun|postun|triggerun) export STAGE=uninstall ;; \ *) export STAGE=unknown ;; \ esac \ }
脚本段内调用示例:
%pre %setup_stage_detection stage_detect if [ "$STAGE" = "install" ]; then # 安装前逻辑 fi
关键说明
%{__spec_script_section}是RPM内置宏,直接返回当前执行的脚本段原始名称(不带百分号),比解析$1/$2更可靠,尤其适配触发器场景。- 两种方案均只需在SPEC顶部定义一次,所有脚本段仅需调用对应宏/函数即可,无需逐个修改逻辑。
- 升级场景下,RPM会先执行安装类脚本段,再执行卸载类脚本段,该方案可自动识别对应阶段。
内容的提问来源于stack exchange,提问作者David Davidson
相关产品推荐
相关产品推荐

