如何通过 Systemd DBus API 提取服务状态?
Posted
技术标签:
【中文标题】如何通过 Systemd DBus API 提取服务状态?【英文标题】:How to extract service state via Systemd DBus API? 【发布时间】:2017-09-15 22:16:36 【问题描述】:我正在尝试使用Systemd
D-Bus API 提取open***.service
状态。
In [1]: import dbus
In [2]: sysbus = dbus.SystemBus()
In [3]: systemd1 = sysbus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1')
In [4]: manager = dbus.Interface(systemd1, 'org.freedesktop.systemd1.Manager')
In [5]: service = dbus.Interface(systemd1, 'org.freedesktop.systemd1.Service')
In [6]: unit = dbus.Interface(systemd1, 'org.freedesktop.systemd1.Unit')
In [7]: unit.ActiveState('open***.service')
---------------------------------------------------------------------------
DBusException Traceback (most recent call last)
<ipython-input-7-22857e7dcbd7> in <module>()
----> 1 unit.ActiveState('open***.service')
/usr/local/lib/python3.4/dist-packages/dbus/proxies.py in __call__(self, *args, **keywords)
68 # we're being synchronous, so block
69 self._block()
---> 70 return self._proxy_method(*args, **keywords)
71
72 def call_async(self, *args, **keywords):
/usr/local/lib/python3.4/dist-packages/dbus/proxies.py in __call__(self, *args, **keywords)
143 signature,
144 args,
--> 145 **keywords)
146
147 def call_async(self, *args, **keywords):
/usr/local/lib/python3.4/dist-packages/dbus/connection.py in call_blocking(self, bus_name, object_path, dbus_interface, method, signature, args, timeout, byte_arrays, **kwargs)
649 # make a blocking call
650 reply_message = self.send_message_with_reply_and_block(
--> 651 message, timeout)
652 args_list = reply_message.get_args_list(**get_args_opts)
653 if len(args_list) == 0:
DBusException: org.freedesktop.DBus.Error.UnknownMethod: Unknown method 'ActiveState' or interface 'org.freedesktop.systemd1.Unit'.
In [8]: manager.GetUnit('open***.service')
Out[8]: dbus.ObjectPath('/org/freedesktop/systemd1/unit/open***_2eservice')
In [9]: u = manager.GetUnit('open***.service')
In [10]: u.ActiveState
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-10-6998e589f206> in <module>()
----> 1 u.ActiveState
AttributeError: 'dbus.ObjectPath' object has no attribute 'ActiveState'
In [11]: manager.GetUnitFileState('open***.service')
Out[11]: dbus.String('enabled')
有一个ActiveState
属性,即contains a state value that reflects whether the unit is currently active or not
。我已经成功阅读了UnitFileState
,但是我不知道如何阅读ActiveState
属性。
【问题讨论】:
【参考方案1】:在看了some random examples [more permanent link] 之后,我遇到了一些运气
import dbus
sysbus = dbus.SystemBus()
systemd1 = sysbus.get_object('org.freedesktop.systemd1',
'/org/freedesktop/systemd1')
manager = dbus.Interface(systemd1, 'org.freedesktop.systemd1.Manager')
service = sysbus.get_object('org.freedesktop.systemd1',
object_path=manager.GetUnit('open***.service'))
interface = dbus.Interface(service,
dbus_interface='org.freedesktop.DBus.Properties')
print(interface.Get('org.freedesktop.systemd1.Unit', 'ActiveState'))
[编辑:] 记录版本,以防万一:
dbus.version == (1, 2, 14)
systemd 244 (244.1-1-arch)
Python 3.8.1
【讨论】:
【参考方案2】:您可能需要调用dbus.Interface(sysbus.get_object('org.freedesktop.systemd1', u), 'org.freedesktop.systemd1.Unit')
并访问该对象的ActiveState
属性。您的代码当前尝试访问对象 path 上的 ActiveState
属性,该对象不是对象本身。
【讨论】:
以上是关于如何通过 Systemd DBus API 提取服务状态?的主要内容,如果未能解决你的问题,请参考以下文章
通过 python 和 dbus 启动用户 systemd 服务
与 SystemD 的 Linux DBus 远程 TCP 连接失败