When working with systemd services in automation scripts or monitoring tools, the standard systemctl status
output isn't machine-friendly. While systemd provides JSON output capabilities, applying them to service status requires specific approaches.
The correct way to get JSON-formatted service status is to use systemctl show
instead of systemctl status
:
systemctl show snapd.service --property=LoadState,ActiveState,SubState,UnitFileState --no-pager --output=json
This will return clean JSON like:
{
"LoadState": "loaded",
"ActiveState": "active",
"SubState": "running",
"UnitFileState": "enabled"
}
For more comprehensive status including PID and uptime:
systemctl show snapd.service --all --no-pager --output=json
This returns all available properties in JSON format:
{
"Type": "notify",
"Restart": "no",
"MainPID": "738",
"ActiveEnterTimestampMonotonic": "123456789",
"ConditionResult": "yes",
...
}
For a hybrid approach that includes both structured data and human-readable status:
{
"status": "$(systemctl status snapd.service --no-pager)",
"properties": $(systemctl show snapd.service --no-pager --output=json)
}
Here's how to process the JSON in a Python script:
import json
import subprocess
def get_service_json(service_name):
cmd = [
"systemctl", "show", service_name,
"--no-pager", "--output=json"
]
result = subprocess.run(cmd, capture_output=True, text=True)
return json.loads(result.stdout)
status = get_service_json("snapd.service")
print(f"Service is {status['ActiveState']} (PID: {status['MainPID']})")
When automating system administration tasks, developers often need to parse service status information programmatically. While systemctl status
provides human-readable output, the JSON format is far more useful for scripting and integration with monitoring tools.
Systemd does provide JSON output capabilities through the --output=json
flag, but this currently only works for journal entries, not service status metadata. The command:
systemctl status servicename --output=json --plain
Returns a hybrid output where only the journal portion is properly formatted JSON, while the service status remains in text format.
Method 1: Using systemctl show
The most reliable approach is to use systemctl show
which outputs properties in key=value format that can be converted to JSON:
systemctl show snapd.service --no-page
To convert this to JSON, you can use a simple Python script:
import json
import subprocess
def get_service_json(service_name):
output = subprocess.check_output(
["systemctl", "show", service_name, "--no-page"]
).decode()
result = {}
for line in output.splitlines():
if "=" in line:
key, value = line.split("=", 1)
result[key] = value
return json.dumps(result, indent=2)
print(get_service_json("snapd"))
Method 2: Combining show and list-units
For more comprehensive information including the relationship between units:
systemctl list-units --all --no-legend --no-pager -o json snapd.service
If you only need certain fields (Loaded, ActiveState, etc.), you can query them directly:
systemctl show snapd.service --property=LoadState,ActiveState,SubState --no-page
Convert to JSON with jq:
systemctl show snapd.service --property=LoadState,ActiveState,SubState --no-page |
awk -F= '{print "\"" $1 "\": \"" $2 "\""}' |
jq -n 'reduce inputs as $line (.; . + ($line | fromjson))'
Newer versions include better JSON support. Try:
systemctl show snapd.service --json=pretty