Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check in a bash script, if some software is installed or not?

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.

like image 225
user2966991 Avatar asked Dec 28 '13 14:12

user2966991


People also ask

How will you check whether a command exists and whether it is built in or not?

type -P command Example #!/bin/bash # Use Bash builtin called type to determine whether a command exists or not # Use full path if possible...

Is test a bash command?

On Unix-like operating systems, test is a builtin command of the Bash shell that tests file attributes, and perform string and arithmetic comparisons.

Which command is used to check whether the file is present or not?

While checking if a file exists, the most commonly used file operators are -e and -f. The '-e' option is used to check whether a file exists regardless of the type, while the '-f' option is used to return true value only if the file is a regular file (not a directory or a device).


1 Answers

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
like image 92
Dmitry Alexandrov Avatar answered Oct 11 '22 08:10

Dmitry Alexandrov