70

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?

73

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.

  • 2
    You 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 [...] – Chris Down Apr 2 '14 at 4:05
  • 1
    I 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. – FGreg Sep 9 '15 at 20:37
  • @FGreg good call... I've replaced the return statements with calls to true and false, so the function is easily readable yet returns the output bash expects. – Doktor J Sep 9 '15 at 22:33
  • 5
    OMG 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. Feb 4 '16 at 22:44
19

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.

  • +1 because this is faster – Freddie Fabregas Nov 12 '18 at 12:38
  • Definitely faster, because rpm is local package manager. yum is for dealing with packages in remote repositories – Sergiy Kolodyazhnyy Jan 25 at 10:50
8

Simpler oneliner:

yum -q list installed packageX &>/dev/null && echo "Installed" || echo "Not installed"
0

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.

0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.