Check if service exists in bash (CentOS and Ubuntu)
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
Justin
Updated on August 31, 2021Comments
-
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?