如果软件包已安装,则 RPM 退出代码为非零

如果软件包已安装,则 RPM 退出代码为非零

我创建了一个新脚本,用于在没有互联网的情况下在 CentOS 7 上安装一些本地软件包。我希望脚本在出现任何错误时退出

set -e
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
rpm --import ./RPM-GPG-KEY-mysql
rpm -ivh ./epel-release-7-11.noarch.rpm
rpm -ivh ./okay-release-1-1.noarch.rpm
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-OKAY

问题是,当一个包已经安装时,rpm将会产生一个错误代码。

package epel-release-7-11.noarch is already installed
echo $?
1

这会导致脚本退出。

有没有不使用 if 条件判断的方法可以修复该问题?

注意:我只想避免已安装软件包的退出代码 1。我不想使用--force在冲突时具有攻击性的。我也不想使用||true或删除set -e

答案1

使用 dnf: dnf localinstall file.rpm

答案2

轻微的死神撞击......但当我尝试使用 rpm 通过 ansible playbook 合并多个软件包(ffmpeg 及其依赖项)的安装时,我也有类似的要求,这篇文章是我在寻找答案时最终到达的少数地方之一,所以我想我也会在这里添加我的替代解决方案,以防它对其他人有帮助。

这符合我的要求。ymmv:

rpm --replacepkgs -i package.rpm

这样做的好处是:

  1. 如果尚未安装软件包,请确保安装它们。
  2. 如果任何软件包已经安装,则不会返回“非零”退出代码,避免我的 ansible playbook(或因错误退出的脚本)退出,但允许其他类型的错误返回“非零”并进行处理。
  3. 如果尚未安装,则不需要安装“dnf”(如接受的答案所用)。

但它的缺点是不具有幂等性(它会“改变”事物,即使它们不需要改变),并且使用循环来执行不必要的任务。

对于我来说,在我的特定情况下,这是一个可以接受的权衡,因为我需要安装一堆软件包,其中一些可能已经安装,但这些软件包相当小,安装或“重新安装”它们并不需要很长时间。而且我可以根据 ffmpeg 二进制文件的存在来决定是否运行 rpm 命令,这意味着它实际上不应该不必要地运行。

插图

  • 尝试“正常”安装。rpm 报告软件包“已安装”,ffmpeg 软件包未安装,退出代码为“16”(我相信等于遇到的“错误”数量。即“已安装”软件包的数量):
[root@app ffmpeg-rpms]# rpm -i *.rpm ; echo $?
        package libogg-1.1.3-1.2.i386 is already installed
        (... snip - multiple packages listed here as "already installed" ...)
        package faad2-libs-2.6.1-5.el5.i386 is already installed
16

[root@app ffmpeg-rpms]# which ffmpeg
/usr/bin/which: no ffmpeg in (/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin)
  • 使用“--replacepkgs”再次尝试 - ffmpeg 包安装,退出代码为“0”:
[root@app ffmpeg-rpms]# rpm --replacepkgs -i *.rpm ; echo $?
0

[root@app ffmpeg-rpms]# which ffmpeg
/usr/bin/ffmpeg

相关内容