Slight necro-bump... but I had a similar requirement when trying to incorporate the installation of multiple packages (ffmpeg and its dependencies) via an ansible playbook using rpm, and this post is one of the few places I ended up when looking for an answer, so I thought I'd add my alternative solution here too in case it helps someone else.
This fitted my requirements. ymmv:
rpm --replacepkgs -i package.rpm
This has the benefit of:
- Ensuring that the packages get installed if they aren't already.
- Not returning a "non-zero" exit code if any of the packages are already installed, avoiding my ansible playbook (or a script that exits on errors) from exiting, but allowing for other types of errors to return "non-zero" and be handled.
- Not requiring the installation of "dnf" if it isn't already installed (as used by the accepted answer).
But it has the downside of not being idempotent (it will "change" things even though they don't need to be changed), and using cycles to perform a task that isn't necessary.
For me, in my particular situation, this was an acceptable trade-off, as I needed to install a bunch of packages, some of which might already be installed, but the packages were are quite small and it didn't take long to install or "re-install" them. And I can key off the existence of the ffmpeg binary to decide whether to run the rpm command or not, meaning it shouldn't really run unnecessarily.
Illustration:
- Try to install "normally".
rpm reports packages "already installed", ffmpeg package doesn't install, exit code is "16" (equal to the number of "errors" encountered, I believe. i.e. the number of packages "already installed"):
[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)
- Try again with "--replacepkgs" - ffmpeg package installs, and exit code is "0":
[root@app ffmpeg-rpms]# rpm --replacepkgs -i *.rpm ; echo $?
0
[root@app ffmpeg-rpms]# which ffmpeg
/usr/bin/ffmpeg
|| true
or check if the package is installed before you install withrpm -i --test ... && rpm -i ...
Why don't you want to use || or set -e or if cases in the first place?