5

I am not happy with the output of systemctl

I have a script which parses the output of

systemctl list-units -t service --full --all

The beginning of the output look like this:

  UNIT                                   LOAD      ACTIVE     SUB          JOB   DESCRIPTION                                                                  
  after-local.service                    loaded    inactive   dead               /etc/init.d/after.local Compatibility                                        
● amavis.service                         not-found inactive   dead               amavis.service                                                               
  apparmor.service                       loaded    active     exited             Load AppArmor profiles                                                       
  auditd.service                         loaded    active     running            Security Auditing Service                                   

On a different systemd the column with the dot (before amavis.service) does not exist.

Is there a machine/script readable output of systemctl?

guettli
  • 3,591
  • 17
  • 72
  • 123

2 Answers2

13

I use this for machine-parsable output, adding --plain --no-legend, for example:

systemctl list-units -t service --full --all --plain --no-legend
guettli
  • 3,591
  • 17
  • 72
  • 123
  • 1
    Sometimes, when there is a pending job for any unit in the list, it includes an additional column with the job status (eg.: "starting") which breaks parsing, because, for other units (that don't have any job), the value in that extra column is blank. – Luke 10X May 17 '23 at 15:02
2

you can get json (or json-pretty) output by setting the --output flag:

systemctl list-units \
  --type service \
  --full \
  --all \
  --output json \
  --no-pager

if your version of systemctl is without json output support, you can get json like so:

systemctl list-units \
  --type service \
  --full \
  --all \
  --plain \
  --no-legend \
  --no-pager \
  | sed 's/ \{1,\}/,/g' \
  | jq \
    --raw-input \
    --slurp \
    'split("\n") | map(split(",")) | .[0:-1] | map( { "unit": .[0], "load": .[1], "active": .[2], "sub": .[3] } )'
grenade
  • 312
  • 1
  • 3
  • 8