I am trying to write a script that installs packages, but if it fails at any point later in the script rolls back whatever it installed. Of course if the user has already previously installed a package I don't want to uninstall it out from under them. How can my script tell whether a package has been previously installed via yum?
5 Answers
I found the following on a semi-related StackOverflow question; the answer I needed didn't actually quite answer the question there (and was not selected as the correct answer) so I figured I'd post it here for others to find easier.
yum list installed PACKAGE_NAME
This command returns some human-readable output, but more importantly returns an exit status code; 0 indicates the package is installed, 1 indicates the package is not installed (does not check whether the package is valid, so yum list installed herpderp-beepbopboop
will return a "1" just as yum list installed traceroute
will if you don't have traceroute installed). You can subsequently check "$?" for this exit code.
Since the output is somewhat counter-intuitive, I used @Chris Downs' "condensed" version below in a wrapper function to make the output more "logical" (i.e. 1=installed 0=not installed):
function isinstalled {
if yum list installed "$@" >/dev/null 2>&1; then
true
else
false
fi
}
usage would be
if isinstalled $package; then echo "installed"; else echo "not installed"; fi
EDIT:
Replaced return
statements with calls to true
and false
which help make the function more readable/intuitive, while returning the values bash expects (i.e. 0 for true, 1 for false).
If you're just checking for one package in your script, you may just be better off testing yum list installed
directly, but (IMHO) the function makes it easier to understand what's going on, and its syntax is much easier to remember than yum
with all the redirects to supress its output.
-
2You don't need to manually check the value of
$?
, just wrap the command in a conditional:if yum list installed "$package" >/dev/null 2>&1; then [...]
Commented Apr 2, 2014 at 4:05 -
1I think your echo statements are reversed, no?
isInstalled
returns 1 if the package is installed; but 1 is evaluated to false in bash so "not installed" is echoed.– FGregCommented Sep 9, 2015 at 20:37 -
@FGreg good call... I've replaced the
return
statements with calls totrue
andfalse
, so the function is easily readable yet returns the output bash expects.– Doktor JCommented Sep 9, 2015 at 22:33 -
5OMG it's the 21st century, can't they have a proper option to tell if a package is installed so I don't have write functions or one liners!?– Sunil D.Commented Feb 4, 2016 at 22:44
Not exactly fulfilling the precondition of the question "via yum" but faster than "yum -q list" is:
rpm -q <package_name>
which returns the exact name of the possibly installed version as well as the error code "0" if installed and "1" if not.
-
Definitely faster, because
rpm
is local package manager.yum
is for dealing with packages in remote repositories Commented Jan 25, 2019 at 10:50
Simpler oneliner:
yum -q list installed packageX &>/dev/null && echo "Installed" || echo "Not installed"
A handy script for yum:
#!/bin/sh
pckarr=(wget mlocate bind-utils ANY_RANDOM_PACKAGE_NAME)
yum update -y
for i in ${pckarr[*]}
do
isinstalled=$(rpm -q $i)
if [ ! "$isinstalled" == "package $i is not installed" ];
then
echo Package $i already installed
else
echo $i is not INSTALLED!!!!
yum install $i -y
fi
done
updatedb
In pckarr array, list those packages which you want to install or check if that is installed.
You can also read the return value $?
from yum. Should be 0 if everything worked or positive depending on what kind of issues yum ran into. This is a good way if you want to take different actions if something fails.