RPM 中的 %config 和 %config(noreplace)
打开一个 rpm spec 文件,在 %files
段有一个指令很常见:%config(noreplace)
,这个指定到底是干什么用的呢?
答案是,该指令决定如果一个文件被管理员修改过后,下次更新该文件所在的rpm包时,该文件的存在状态。例如,一般升级软件时,配置文件是不会变化的,而主程序则一般需要被升级(替换)。
对于 spec 文件中在 %files
段的某一个文件,我们要讨论三种情况:
- 没有带
%config
指令。例如:%{_sbindir}/redis-server
- 带了
%congfig
指令。例如:%config %{_sysconfdir}/redis/redis.conf
- 带了
%config(noreplace)
指令。例如:%config(noreplace) %{_sysconfdir}/redis/redis.conf
具体一点,包含如下场景:
1. 一个文件没有被 %config
或 %config(noreplace)
指令配置
此时,不管该文件在安装完成后,有没有在本地被修改过,当升级该 rpm 包时,该文件会被这个新的 rpm 包的里的同名文件替换,(旧文件被删除)。
2. 一个文件被 %config
指令配置
此时包含如下情况:
- 该文件在新的 rpm 包里相对之前的 rpm 有变化,且在本地没有被修改过。
此时执行rpm -Uvh xxxx时,新rpm包里的该文件会替换旧的文件。(旧文件被删除)
- 该文件在新的 rpm 包里相对之前的 rpm 有变化,且在本地被修改过。
此时执行 rpm -Uvh xxxx 时,新 rpm 包里的该文件会替换掉掉旧的文件,旧的文件会被保存为 xx.rpmsave,如 /etc/redis/redis.conf.rpmsave。
- 该文件在新的 rpm 包里相对之前的 rpm 没有变化,且在本地没有被修改过。
此时执行r pm -Uvh xxxx 时,新 rpm 包里的该文件会替换掉旧的文件。(旧文件被删除)
- 该文件在新的 rpm 包里相对之前的 rpm 没有变化,且在本地被修改过。
此时执行 rpm -Uvh xxxx 时,新 rpm 包里的该文件不会覆盖旧的文件,旧文件保持不变。
3. 一个文件被 %config(noreplace)
指令配置
此时包含如下情况:
- 该文件在新的 rpm 包里相对之前的 rpm 有变化,且在本地没有被修改过。
此时执行 rpm -Uvh xxxx 时,新 rpm 包里的该文件会替换旧的文件。(旧文件被删除)
- 该文件在新的 rpm 包里相对之前的 rpm 有变化,且在本地被修改过。
此时执行 rpm -Uvh xxxx 时,旧文件保持不变,新 rpm 包里的该文件并重命名为 xx.rpmnew,例如/etc/redis/redis.conf.rpmnew。
- 该文件在新的 rpm 包里相对之前的 rpm 没有变化,且在本地没有被修改过。
此时执行 rpm -Uvh xxxx 时,新 rpm 包里的该文件会替换旧的文件。(旧文件被删除)
- 该文件在新的 rpm 包里相对之前的 rpm 没有变化,且在本地被修改过。
此时执行 rpm -Uvh xxxx 时,新rpm包里的该文件不会覆盖旧的文件,旧文件保持不变。
4.总结
- 如果一个文件在
%files
段没有被%config
或%config(noreplace)
指令配置,则执行 rpm -Uvh 时,该文件会无条件被新文件替换。 - 无论一个文件有没有被
%config
或%config(noreplace)
指令配置,只要改文件在本地没有被编辑过,则执行 rpm -Uvh 时,该文件会被新文件替换。 - 一个被
%config
或%config(noreplace)
指令配置的文件,如果被编辑过,那么在 rpm 更新时,如果新的 rpm 包中该文件没有修改,则该文件不会被新 rpm 包中的文件替换,之前做的编辑依然有效。 - 一个被
%config
指令配置的文件,如果被编辑过,且新的 rpm 包中该文件有修改,则该文件会被重命名为 xx.rpmsave,新文件会替代原文件。 - 一个被
%config(noreplace)
指令配置的文件,如果被编辑过,且新的 rpm 包中该文件有修改,则该文件不会被新的 rpm 包中的文件替换,之前做的编辑依然有效;但新 rpm 包中的同名文件会被重命名为 xx.rpmnew。
参考: