所以我有这个问题,在 RPM 的版本“1”中有一个符号目录。我们就叫它“/foo”吧。澄清一下,“/foo”是在版本“1”的 RPM 中定义的。在版本“2”中,我希望在安装后脚本中以编程方式创建“/foo”。但是当我从我的 RPM 规范中删除“/foo”时,它会在安装后脚本已经运行后删除“/foo”。有没有办法防止这种情况?那就是告诉 RPM 不要删除“/foo”,即使它不再由 RPM 管理?
4 回答
我假设您的意思是在升级操作期间。如果是这样,RPM 正在正确地清理旧文件。您可以尝试将未注册的文件放入目录中(通过您的%postinstall
)。“ echo > /foo/.keepdir
”或类似的东西。然后它可能会不理会它,因为它无法识别文件并且不应该删除%files
版本 1 部分中未列出的文件。
但是,我会注意,如果您创建和使用目录/foo
,您应该在您的包中声明它,以便当有人出现并尝试“ rpm -q --whatprovides /foo
”时,他们可以知道它来自哪里以及谁使用它。
您可以创建没有 /foo 的 RPM 版本 1.1,升级到 1.1,然后升级到 2。
您可以使用%posttrans
而不是%post
解决此问题。但是请注意,posttrans 脚本应该用纯 lua 编写。这是因为它们理论上可以在没有任何 shell/库的情况下在 kickstart 中运行,除了 RPM 本身。
scriptlet 的完整顺序(取自Fedora 打包指南)如下:
- %pretrans 新包
- %pre 新包
- (包安装)
- %post 新包
- %triggerin 其他包(通过安装新包来触发)
- %triggerin 新包(如果有的话)
- 旧包的 %triggerrun (如果它是通过卸载旧包触发的)
- %triggerrun of other packages(通过卸载旧包触发)
- 旧包的%preun
- (去除旧包装)
- 旧包的%postun
- 旧包的%triggerpostun(如果它是通过卸载旧包引起的)
- 其他软件包的 %triggerpostun(如果它们是通过卸载旧软件包设置的)
- %posttrans 新包
我会注意到,通常不建议在 posttrans 中进行任何复杂的工作。您在 %posttrans 中引入的任何问题在更新期间都很难修复。相反,您可以提供管理员应该在更新后运行的支持脚本。应用程序可以优雅地出错并提醒他们这样做(在某些情况下,我猜这是不可能的,但通常有一种方法可以很好地做到这一点)。或者应用程序本身可以检测到这一点并根据需要正确符号链接/复制依赖项。
最后一个警告:处理更新时 RPM 存在问题,其中一个 RPM 具有指向目录的符号链接,而新 RPM 具有目录而不是(或反向)。如果您看到交易错误,这可能是罪魁祸首。这实际上只能在 %pretrans/%posttrans 脚本中修复
尝试在规范文件的 %files 部分将 foo 标记为 %config(noreplace) 文件。这将防止 rpm 在升级期间修改文件。