检查 bash 中是否存在服务(CentOS 和 Ubuntu)

问题描述 投票:0回答:11

bash 中检查服务是否已安装的最佳方法是什么?它应该可以在 Red Hat (CentOS) 和 Ubuntu 上运行吗?

思考:

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

还可以使用

service
命令并检查返回码。

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

最好的解决方案是什么?

linux bash ubuntu service centos
11个回答
37
投票

要获取一项服务的状态而不“ping”所有其他服务,您可以使用以下命令:

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

顺便说一句,这是 bash(自动)完成中使用的内容(请参阅文件 /usr/share/bash-completion/bash_completion,查找 _services):

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

或更详细的解决方案:

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

希望有帮助。


23
投票

Rustam Mamat 获得此荣誉:

如果您列出了所有服务,您可以 grep 结果来查看其中的内容。例如:

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

11
投票

在 SystemD 系统上:

serviceName="Name of your service"

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

在 Upstart 系统上:

serviceName="Name of your service"

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

在 SysV (System V) 系统上:

serviceName="Name of your service"

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

5
投票

在 systemd 中(尤其是在 Debian 中),使用此处的各种答案似乎无法正常工作。对于某些服务,例如

pure-ftpd
,如果它处于禁用模式,当您触发此命令时,它不会显示在服务列表中:

systemctl --all --type service

当您再次开始时,

pure-ftpd
systemctl start pure-ftpd
列表将再次出现。因此,使用
systemctl --all --type service
列出服务并不适用于所有服务。看看这里了解更多信息。

因此,这是迄今为止最好的代码(对@jehon的答案的改进),用于检查服务是否存在(即使它的状态为不活动、死亡或任何状态):

#!/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

说明:

如果

systemctl status
找到一个服务,它必须有一个文本“Active:”,我们使用 grep 进行过滤,它将返回 0。如果没有“Active:”文本,它将返回 1。

如果

systemctl status
没有找到“Active:”文本,它将打印出一个标准错误。因此,我使用重定向
2> /dev/null
来重定向标准错误。例如,如果您正在寻找不存在的服务,如果您不设置该错误重定向,您将收到此错误消息:

Unit pure-ftpdd.service could not be found.

如果您正在编写脚本,我们不希望出现上述标准错误消息

编辑:

另一种方法是列出能够检测 Debian 系统的@Anthony Rutledge 指出的禁用服务的单元文件:

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

但是使用此方法并不总是有效,特别是对于较旧的系统,因为使用此命令可能无法检测到某些单元文件,如此处中所述。另外,如果您有需要过滤的大型单元文件,则使用此方法会更慢(正如 @ygoe 关于小型计算机上的重负载所评论的那样)。


2
投票

为了构建 Joel B 的答案,这里它是一个函数(添加了一点灵活性。请注意完全缺乏参数检查;如果您不传入 2 个参数,这将会中断):

#!/bin/sh

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

serviceCommand apache2 status

2
投票

阅读一些 systemd 手册页后...

https://www.freedesktop.org/software/systemd/man/systemd.unit.html

...和 systemd.services(5)....

...还有一篇不错的小文章...

https://www.linux.com/learn/understanding-and-using-systemd

我相信这可能是一个答案。

systemctl list-unit-files --type service

通过管道连接到 awk {'print $1'} 以获取服务单元的列表。

再次通过管道连接到 awk 以独占获取服务名称。使用 -F 将字段分隔符更改为句点。

awk -F。 {'打印 1 美元'}

总结:

systemctl list-unit-files --type service | awk {'print $1'} | awk -F. {'print $1'} 


通过基本解决方案的变化和增强,您可以通过将

for
循环与
systemctl is-active $service
相结合来确定系统服务的状态。


1
投票
#!/bin/sh

service=mysql
status=$(/etc/init.d/mysql status)
print "$status"
#echo $status > /var/log/mysql_status_log

1
投票
if systemctl cat xxx >/dev/null 2>&1; then
    echo yes
fi

0
投票
var=$(service --status-all | grep -w "$Service")
if [ "output" != "" ]; then
    #executes if service exists
else
    #executes if service does not exist
fi

$Service 是您想知道是否存在的服务的名称。 var 将包含类似

的内容
[+]    apache2

如果该服务确实存在


0
投票

扩展@jehon 的答案。我相信简单的 grep

-Fq
选项很容易导致错误。如果有类似的命名服务,它也匹配。

然而这个?

service --status-all 2>&1 | grep -Pq '.*\s\Kxxx$'

将 xxx 替换为所需的服务或应用程序名称将与名称完全匹配。


-1
投票

试试这个,因为

ps
命令可以在Ubuntu和RHEL中使用,这应该在两个平台上都可以工作。

#!/bin/bash
ps cax | grep mysqld > /dev/null
if [ $? -eq 0 ]; then
  echo "mysqld service exists"
else
  echo "mysqld service not exists"
fi
© www.soinside.com 2019 - 2024. All rights reserved.