Python代码检查服务是否正在运行?

23

我正在使用Python 2.7来检查服务是否正在运行。 我已经创建了自己的服务并将其放置在/etc/init.d中。 我正在使用树莓派。

现在,要正常检查服务的状态,我们可以执行以下操作:

service my_service status

但是我该如何从Python代码中获取服务的状态呢?

谢谢

7个回答

41

我可能晚回答了几年,但这是我发现的一个简单解决方案

import os  # I think it's better to use subprocess for this. but quick code for example

status = os.system('systemctl is-active --quiet service-name')
print(status)  # will return 0 for active else inactive.

19

通过使用os.system(),您可以获取执行的返回代码;0表示正在运行,768表示停止

>>> import os
>>> stat = os.system('service sshd status')
Redirecting to /bin/systemctl status  sshd.service
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2017-10-05 09:35:14 IDT; 29s ago
     Docs: man:sshd(8)
           man:sshd_config(5)
  Process: 620 ExecStart=/usr/sbin/sshd $OPTIONS (code=exited, status=0/SUCCESS)
 Main PID: 634 (sshd)
   CGroup: /system.slice/sshd.service
           └─634 /usr/sbin/sshd
>>> stat
0  <--  means service is running

>>> os.system('service sshd stop')
Redirecting to /bin/systemctl stop  sshd.service
0  <-- command succeeded

>>> os.system('service sshd status')
Redirecting to /bin/systemctl status  sshd.service
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Thu 2017-10-05 09:41:58 IDT; 10s ago
     Docs: man:sshd(8)
...
768 <-- service not running

返回码是从执行中返回的代码。根据 service 的手册:

退出代码 service 调用 init 脚本并返回脚本的状态。

因此,这取决于所执行的 init 脚本。你可以安全地说除了 0 以外的任何返回码意味着服务未运行。

或者,您可以使用以下方法检查进程是否正在运行:

>>> os.system('ps aux | grep sshd | grep -v grep | wc -l')
2
>>> os.system('ps aux | grep sshd123 | grep -v grep | wc -l')
0

你已经接近成功了。你需要在代码中获取状态,而不仅仅是向用户显示它。 - Ignacio Vazquez-Abrams
嗨,我按照你说的做了。但是我得到 768 作为输出。 - S Andrew
768 表示服务未运行。 - Chen A.
@SAndrew 这取决于初始化脚本。你可以安全地假设 0 表示正在运行,其他任何值表示未运行。 - Chen A.
@SAndrew,你可以检查进程是否正在运行;我已经添加了一个示例。 - Chen A.
显示剩余2条评论

15
有点离题的回答(针对Python3)。
在Python3中,您可以使用pystemd来实现此目的。它通过systemd的dbus API与其进行通信,因此比仅执行systemctl并解析其输出要好。
from pystemd.systemd1 import Unit
unit = Unit(b'my_service.service')
unit.load()
print(unit.Unit.SubState)

P.S. 最好使用subprocess模块,而不是使用os.system()。

9

使用subprocess:

import subprocess

stat = subprocess.call(["systemctl", "is-active", "--quiet", "ssh"])
if(stat == 0):  # if 0 (active), print "Active"
    print("Active")

此外,我发现这个答案很好地解释了为什么要使用subprocess而不是os.system。


这是我认为2022年最佳答案。超级简单可靠。 - Sean McCarthy

-1

你可以参考我的代码:

#!/usr/bin/env python
import os

def isActive(daemon):
    command = "systemctl is-active " + daemon + " > tmp"
    os.system(command)
    with open('tmp') as tmp:
        tmp = tmp.read()
        if "active" in tmp:
            os.remove('tmp')
            return 1
    return 0


sshd = "sshd"

print(isActive(sshd))

1
你提出的方案相较于现有的答案,有哪些优点? - Jeremy Caney
你好 @Jeremy Caney:谢谢你的提醒。我刚刚提供了另一种方法,如果有人在谷歌上搜索解决方案,他们将有另一个选择。 - Huan Phan

-1
使用os.popen方法获取cmd命令的输出,并通过if语句进行检查。
import os

STATE = os.popen('sc query ServiceName').read()
if STATE.find("RUNNING") != -1:
  print("Service is working")
else:
  print("Service is not working")

谢谢您对 Stack Overflow 社区的贡献。这可能是一个正确的答案,但如果您能提供额外的代码解释,那么开发人员将能够理解您的推理过程,这对于不熟悉语法或难以理解概念的新开发人员尤其有用。您是否可以编辑您的答案以包含更多细节,以造福整个社区? - Jeremy Caney

-5

你需要做的第一件事是明确你所说的“运行”是指什么:

  • systemd 给出了正常状态
  • 进程正在运行/在 PS 中显示
  • 实际上工作,即可以获取网页或通过本地主机 ssh 连接到框中

然后编写执行测试的代码或查找适合您的工具。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接