如何以json格式获取systemd状态?

Sta*_*nov 10 json systemd

我想以机器可读的形式获取服务状态详细信息(已加载、已启用、活动、正在运行、因为、主 PID),并且我知道 systemd 工具有--output=json选项,但如果我这样做:

 systemctl status servicename --output=json --plain
Run Code Online (Sandbox Code Playgroud)

我看到类似的东西:

? snapd.service - Snappy daemon
   Loaded: loaded (/lib/systemd/system/snapd.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2018-04-16 11:20:07 MSK; 4h 45min ago
 Main PID: 738 (snapd)
    Tasks: 10 (limit: 4915)
   CGroup: /system.slice/snapd.service
           ??738 /usr/lib/snapd/snapd

{ "__CURSOR" : "s=461ecb6a4b814913acd57572cd1e1c82;...
Run Code Online (Sandbox Code Playgroud)

日志记录采用 JSON 格式。但是如果可能的话,如何在 JSON 中获取服务状态?

Sta*_*nov 10

以机器可读形式获取服务状态的简单方法:

systemctl show servicename --no-page
Run Code Online (Sandbox Code Playgroud)

此命令以以下key=value格式输出数据:

Type=notify
Restart=always
NotifyAccess=main
...
Run Code Online (Sandbox Code Playgroud)

如果JSON需要格式,您可以使用以下简单的 Python 脚本(Python 2 和 3 兼容)get_service_info.py

import os, sys, subprocess, json
key_value = subprocess.check_output(["systemctl", "show", sys.argv[1]], universal_newlines=True).split('\n')
json_dict = {}
for entry in key_value:
    kv = entry.split("=", 1)
    if len(kv) == 2:
        json_dict[kv[0]] = kv[1]
json.dump(json_dict, sys.stdout)
Run Code Online (Sandbox Code Playgroud)

用法:

get_service_info.py servicename
Run Code Online (Sandbox Code Playgroud)


Dar*_*ari 6

您也可以jq为此使用:

systemctl show --no-page iptables \
    | jq --slurp --raw-input \
        'split("\n")
        | map(select(. != "") 
        | split("=") 
        | {"key": .[0], "value": (.[1:] | join("="))})
        | from_entries'
Run Code Online (Sandbox Code Playgroud)

产生:

{
  "Type": "oneshot",
  "Restart": "no",
  "NotifyAccess": "none",
  "ExecStart": "{ path=/usr/libexec/iptables/iptables.init ; argv[]=/usr/libexec/iptables/iptables.init start ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
  [... like 60 more entries ...],
  "CollectMode": "inactive"
}
Run Code Online (Sandbox Code Playgroud)

jq命令解码:

--slurp - read the whole thing as a really big string
--raw-input - p.s. it's not json input
split("\n") - break the input into an array of lines
map( ... )  - perform some transformation on each array element
select(. != "") - skip blank lines
split("=") - split the current line into array elements at each "="
(.[1:] | join("=")) - avoid mangling values with equal signs
Run Code Online (Sandbox Code Playgroud)

(请注意:如果值本身包含等号,这将截断值。这可能可以解决,但为此目的似乎很好)

{"key": .[0], "value": .[1]}  - build an key/value pair object
Run Code Online (Sandbox Code Playgroud)

(此时map返回一个键/值对象数组)

from_entries - turn an array of "key"/"value" objects into an object
Run Code Online (Sandbox Code Playgroud)

  • 好吧,我可能有一个小书呆子被狙击了。要*不*处理包含等号的值,请将 `.[1]` 替换为 `(.[1:] | join("="))`,这将抓取数组的其余部分并使用等号将其装订在一起迹象。 (2认同)