RPM %config 包更新时未按预期工作,请求技术协助
RPM更新时配置文件被意外删除的问题解决
问题场景
我使用rpmbuild打包软件,spec文件片段如下:
%files %config /etc/somedir/* %config /usr/bin/binary %Postun rm -rf %{_sysconfdir}/%{name} rm -rf %{_bindir}/%{name}
需求是更新包时,覆盖/etc/somedir及其子目录、/usr/bin/binary中已修改的内容,未修改则不操作。但实际更新时,这两个路径被完全删除。
问题原因
- %Postun脚本的执行时机:RPM更新流程是先安装新版本,再卸载旧版本。旧版本的
%Postun会在新版本安装完成后执行,你写的rm -rf直接删除了目标路径,不管是旧版还是新版的文件都会被清掉。 - %config标记的误用:
%config /etc/somedir/*只会匹配目录下的直接文件,不会包含子目录,达不到覆盖整个目录的效果。- 二进制文件
/usr/bin/binary不应该标记为%config,这个标记是给配置文件用的,可执行文件直接放在%files里即可。
- 多余的手动删除:RPM本身已经内置了配置文件的更新逻辑,不需要手动写脚本删除。
解决方案
1. 移除%Postun中的删除命令
删掉%Postun段的两行rm -rf,RPM会自动处理文件的更新与保留。
2. 修正%files段的标记
调整%config的写法,同时修正二进制文件的标记:
%files # 标记整个目录为配置文件,包含所有子目录和文件 %config /etc/somedir/ # 二进制文件直接声明,不需要%config标记 /usr/bin/binary
关于RPM配置文件更新的说明
- 默认
%config逻辑:RPM会对比文件哈希值,若文件未被用户修改,更新时自动覆盖;若已修改,会保留用户的文件(后缀加.rpmsave),同时安装新版本文件(后缀加.rpmnew),交互模式下会询问是否替换。 - 若需要强制覆盖所有配置文件(包括用户修改过的),可以在安装/更新时添加
--replacefiles参数,不建议在spec中硬编码该逻辑,应交给用户选择。
内容的提问来源于stack exchange,提问作者Prab
相关产品推荐
相关产品推荐

