【时间】2026 年 9 月 26 号,dnf install bilibili-1.19.0 在 %postun 阶段挂掉
error: %postun scriptlet failed, exit status 2系统表面看起来一切正常,但 dnf 报事务失败。先查 rpmdb:
$ rpm -q bilibili
bilibili-1.19.0-1.x86_64只有 1.19.0,旧版 1.17.5 已经移除。/usr/bin/bilibili 符号链接正常:
/usr/bin/bilibili → /etc/alternatives/bilibili → /opt/bilibili/bilibili直接运行 bilibili,成功启动。系统没坏,是上游脚本的 bug。
坑
旧包的 %postun 执行:
update-alternatives --remove bilibili /usr/bin/bilibili但新包的 %post 注册的备选路径是 /opt/bilibili/bilibili。update-alternatives --remove 找不到条目,exit 2,dnf 报事务失败。
这是典型的“旧包卸载脚本和新包安装脚本不一致”问题——上游在某个版本把安装路径从 /usr/bin 改到了 /opt/bilibili,但没同步更新 %postun 里的路径。
修复
写了一个容错的 after-remove.sh,用 update-alternatives --query 先查条目存在不,再决定要不要 remove:
#!/bin/bash
# after-remove.sh
BIN="/opt/bilibili/bilibili"
LEGACY="/usr/bin/bilibili"
for path in "$BIN" "$LEGACY"; do
if update-alternatives --query bilibili 2>/dev/null | grep -q "Link: $path"; then
update-alternatives --remove bilibili "$path" 2>/dev/null || true
fi
done
exit 0在 conf/build.json 的 rpm/deb 段用 afterRemove 引用这个脚本。提交到 msojocs/bilibili-linux,开了 PR。
经验
update-alternatives --remove找不到条目时 exit 2,不是幂等的。写%postun或 after-remove 脚本时必须先--query确认条目存在。- dnf 事务失败不等于系统坏了。先查 rpmdb 和符号链接,确认实际状态再决定是否要补救。
- 上游包改了安装路径但没更新卸载脚本,是 RPM 打包里最常见的坑之一。
🎵 Listening companion