Check if service exists in bash (CentOS and Ubuntu)

49,198

Solution 1

To get the status of one service without "pinging" all other services, you can use the command:

systemctl list-units --full -all | grep -Fq "$SERVICENAME.service"

By the way, this is what is used in bash (auto-)completion (see in file /usr/share/bash-completion/bash_completion, look for _services):

COMPREPLY+=( $( systemctl list-units --full --all 2>/dev/null | \
   awk '$1 ~ /\.service$/ { sub("\\.service$", "", $1); print $1 }' ) )

Or a more elaborate solution:

service_exists() {
    local n=$1
    if [[ $(systemctl list-units --all -t service --full --no-legend "$n.service" | sed 's/^\s*//g' | cut -f1 -d' ') == $n.service ]]; then
        return 0
    else
        return 1
    fi
}
if service_exists systemd-networkd; then
    ...
fi

Hope to help.

Solution 2

Rustam Mamat gets the credit for this:

If you list all your services, you can grep the results to see what's in there. E.g.:

# Restart apache2 service, if it exists.    
if service --status-all | grep -Fq 'apache2'; then    
  sudo service apache2 restart    
fi

Solution 3

On a SystemD system :

serviceName="Name of your service"

if systemctl --all --type service | grep -q "$serviceName";then
    echo "$serviceName exists."
else
    echo "$serviceName does NOT exist."
fi

On a Upstart system :

serviceName="Name of your service"

if initctl list | grep -q "$serviceName";then
    echo "$serviceName exists."
else
    echo "$serviceName does NOT exist."
fi

On a SysV (System V) system :

serviceName="Name of your service"

if service --status-all | grep -q "$serviceName";then
    echo "$serviceName exists."
else
    echo "$serviceName does NOT exist."
fi

Solution 4

In systemd (especially in Debian), it doesn't seems to work properly using the various answers from here. For some services like pure-ftpd if it's in disabled mode, it will not show up in service list when you trigger this command:

systemctl --all --type service

and when you start again the pure-ftpd with systemctl start pure-ftpd the list will appear again. So listing the service using systemctl --all --type service will not work for all services. Take a look at this for more information.

So, this is the best code so far (improvement from @jehon's answer) to check if a service is exist (even it has status inactive, dead or whatever status it is):

#!/bin/bash
is_service_exists() {
    local x=$1
    if systemctl status "${x}" 2> /dev/null | grep -Fq "Active:"; then
            return 0
    else
            return 1
    fi
}


if is_service_exists 'pure-ftpd'; then

        echo "Service found!"
else
        echo "Service not found!"
fi

Explanation:

If systemctl status found a service, it must have a text 'Active:' we filter using grep and it would return 0. If there is no 'Active:' text it would return 1.

If systemctl status does not find the 'Active:' text, it will print out a standard error. So, I put redirection 2> /dev/null to redirect the standard error. For example, if you are looking for the non existence service, you would get this error message if you don't put that error redirection:

Unit pure-ftpdd.service could not be found.

We don't want to have the above standard error message if you are doing scripting

EDIT:

Another method is to list out unit files which able to detect disabled service as pointed by @Anthony Rutledge for Debian system:

systemctl list-unit-files --type service | grep -F "pure-ftpd"

But using this method will not always work especially for older system because some unit files might not be detected using this command as explained in here. Also, using this method is slower if you have large unit-files that need to be filtered (as commented by @ygoe about heavy load on a small computer).

Solution 5

To build off of Joel B's answer, here it is as a function (with a bit of flexibility added in. Note the complete lack of parameter checking; this will break if you don't pass in 2 parameters):

#!/bin/sh

serviceCommand() {
  if sudo service --status-all | grep -Fq ${1}; then
    sudo service ${1} ${2}
  fi
}

serviceCommand apache2 status
Share:
49,198
Justin
Author by

Justin

Updated on August 31, 2021

Comments

  • Justin
    Justin over 2 years

    What is the best way in bash to check if a service is installed? It should work across both Red Hat (CentOS) and Ubuntu?

    Thinking:

    service="mysqld"
    if [ -f "/etc/init.d/$service" ]; then
        # mysqld service exists
    fi
    

    Could also use the service command and check the return code.

    service mysqld status
    if [ $? = 0 ]; then
        # mysqld service exists
    fi
    

    What is the best solution?