5

I want to check a list of software, if it is installed or not. if not, it should be displayed and the script should abort/exit. The output should look like following, if I execute the script once:

  wget is not installed
  telnet is not installed

Currently it's looking like following:

  wget is not installed

Execute script again...

  telnet is not installed

The current script is checking for installed software and aborts/exists, if the current checked software is not installed. That's not nice, because you have to run the script more times to identify and check, if each software is installed or not:

  LINUX_DISTRIBUTATION=$(grep -Eo "(Debian|Ubuntu|RedHat|CentOS)" /etc/issue)

  # Debian / Ubuntu
  if [ -f /etc/debian_version ] || [ "$LINUX_DISTRIBUTATION" == "Debian" ] || [ "$LINUX_DISTRIBUTATION" == "Ubuntu" ]; then
          declare -a NEEDED_SOFTWARE_LIST=(bash rsync wget grep telnet sed)

          for SOFTWARE in ${NEEDED_SOFTWARE_LIST[@]}; do
                  dpkg -l | grep -i $SOFTWARE | head -1 | if [[ "$(cut -d ' ' -f 1)" != "ii" ]]; then
                          echo -e "[ ${Red}FAILED ${RCol}]\t$SOFTWARE is NOT installed completely! Please install it...\n";
                          exit 1;
                  fi
          done
  # RedHat / CentOS
  elif [ -f /etc/redhat-release ] || [ "$LINUX_DISTRIBUTATION" == "RedHat" ] || [ "$LINUX_DISTRIBUTATION" == "CentOS" ]; then
          declare -a NEEDED_SOFTWARE_LIST=(bash rsync wget grep telnet sed)

          for SOFTWARE in ${NEEDED_SOFTWARE_LIST[@]}; do
                  if [[ "$(rpm -q $SOFTWARE)" == "package $SOFTWARE is not installed" ]]; then
                          echo -e "[ ${Red}FAILED ${RCol}]\t$SOFTWARE is NOT installed completely! Please install it...\n";
                          exit 1;
                  fi
          done
  else
          echo "[ ${Red}FAILED ${RCol}]\tYour system is currently not supported by this script.";
          exit 1;
  fi

I also think, that my solution is not the best. Can anybody adjust it? Thanks in advance! :)

Hint: I declared the variable "NEEDED_SOFTWARE_LIST" twice, because I thought I will need two "arrays" of software lists, because some distributions needs another software packages.

Sam
  • 7,252
  • 16
  • 46
  • 65
checker284
  • 1,286
  • 3
  • 14
  • 29

1 Answers1

6

Why do you perform a monstrous test if package is installed instead of simply checking availability of certain utilities?

SCRIPTNAME="${0##*/}"

warn() {
    printf >&2 "$SCRIPTNAME: $*\n"
}

iscmd() {
    command -v >&- "$@"
}

checkdeps() {
    local -i not_found
    for cmd; do
        iscmd "$cmd" || { 
            warn $"$cmd is not found"
            let not_found++
        }
    done
    (( not_found == 0 )) || {
        warn $"Install dependencies listed above to use $SCRIPTNAME"
        exit 1
    }
}

checkdeps wget rsync realpath

However, if you want to check if package is installed on Debian, please replace this nightmare

dpkg -l | grep -i $SOFTWARE | head -1 | if [[ "$(cut -d ' ' -f 1)" != "ii" ]]; then

with

if dpkg -l $SOFTWARE; then
Dmitry Alexandrov
  • 1,693
  • 12
  • 14
  • 1
    Much cleaner than my attempt to patch the original. – Floris Dec 28 '13 at 18:05
  • LoL. How short this solution is. :o Thank you very much! :) – checker284 Dec 30 '13 at 19:28
  • One last question: What does the first line "SCRIPTNAME="${0##*/}"" say/mean? And is this solution working for each linux distributation? – checker284 Dec 30 '13 at 19:31
  • 1
    @user2966991 `SCRIPTNAME="${0##*/}` is a line that you can often see among first lines of many bash-scripts. It puts short name of the file containing the script to variable, which may be used to produce proper format of warning / errors (like here) or e. g. to print usage. It have no any relation to your question. It’s here only because I’ve copied code from one of my real scripts. – Dmitry Alexandrov Dec 30 '13 at 21:00
  • @user2966991 This solution is not OS-specific at all. It is pure Bash. Even GNU Coreutils is not required. So it should be working not only for every GNU distribution, but for every system where Bash is installed. – Dmitry Alexandrov Dec 30 '13 at 21:01