8

Is there a way to get shorter/custom output from systemctl status? I really only need the active line prepended with the name of the service. So something like this:

        apache2: active (running) since Thu 2020-02-06 17:20:42 +03; 16min ago
        mongodb: inactive (dead)  since Thu 2020-02-06 17:20:47 +03; 16min ago
rabbitmq-server: active (running) since Thu 2020-02-06 17:20:52 +03; 16min ago
 mongodb-server: active (running) since Thu 2020-02-06 17:20:54 +03; 16min ago
          mysql: active (running) since Thu 2020-02-06 17:20:57 +03; 16min ago

only with color feedback. But I would settle for it without color. Or on two lines plus a blank line like:

● apache2.service - The Apache HTTP Server
   Active: active (running) since Thu 2020-02-06 17:20:42 +03; 16min ago

● mongodb.service - An object/document-oriented database
   Active: inactive (dead) since Thu 2020-02-06 17:20:47 +03; 16min ago

● redis-server.service - Advanced key-value store
   Active: active (running) since Thu 2020-02-06 17:20:52 +03; 16min ago

● rabbitmq-server.service - RabbitMQ Messaging Server
   Active: active (running) since Thu 2020-02-06 17:20:54 +03; 16min ago

● mysql.service - MySQL Community Server
   Active: active (running) since Thu 2020-02-06 17:20:57 +03; 16min ago

This kind of satisfies the latter btw:

systemctl status apache2.service mongodb.service \
redis.service rabbitmq-server.service mysql.service | grep -e Active -e ●

But it messes up the colors doesn't have the whitespace and I kind of expect there is a systemctl option or configuration somewhere where I can get exactly what I want.

3 Answers3

8

So there's no native way in systemctl to format the output in this way, but we can do it anyways by getting a bit creative with pipes.

First, we need a list of all running services on the system:

# systemctl -t service --state=running --no-legend --no-pager

accounts-daemon.service                         loaded active running Accounts Service                                               
atd.service                                     loaded active running Deferred execution scheduler                                   
containerd.service                              loaded active running containerd 
...

No time output. To get that we have to invoke systemctl show against the unit with the --property=ActiveEnterTimestamp flag. Example:

# systemctl show accounts-daemon.service --property=ActiveEnterTimestamp
ActiveEnterTimestamp=Wed 2019-12-11 21:44:50 UTC

Now if only we had a way to staple that output onto the end of the systemctl output.. we do!

This is an ugly one-liner, but it gets the job done:

systemctl -t service --state=running --no-legend --no-pager | cut -d ' ' -f 1 | while read f; do STARTTIME=`systemctl show $f 
--property=ActiveEnterTimestamp | sed 's/ActiveEnterTimestamp=//'`; echo "$f $STARTTIME"; done`

To explain:

  • The cut command is splitting on spaces and taking the first field from systemctl, which is the service name.
  • We enter a while loop that pipes that service name into a variable named $f
  • We create a variable named STARTTIME that contains the systemctl show output with the start time flag.
  • We use sed to strip the actual ActiveEnterTimestamp= text, giving us the time only.
  • Finally, we echo the service name and the cleaned up start time, separated with a space.

The final output looks like this:

accounts-daemon.service Wed 2019-12-11 21:44:50 UTC
atd.service Wed 2019-12-11 21:44:48 UTC
containerd.service Wed 2019-12-11 21:44:50 UTC
Karu
  • 4,922
0

The command systemctl list-units provides a concise overview of active services, displaying one line per service. Here’s how to use it with pattern filtering:


# systemctl list-units sp*
  UNIT                         LOAD   ACTIVE SUB     DESCRIPTION              
  spark-history-server.service loaded active running LSB: Spark history-server
  spark-master.service         loaded active running LSB: Spark master
● spark-thriftserver.service   loaded failed failed  LSB: Spark thriftserver
● spark-worker.service         loaded failed failed  LSB: Spark worker

LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 4 loaded units listed. Pass --all to see loaded but inactive units, too.

Use --state=running,failed,exited to show just specific services:


# systemctl list-units --state=failed sp*
  UNIT                       LOAD   ACTIVE SUB    DESCRIPTION            
● spark-thriftserver.service loaded failed failed LSB: Spark thriftserver
● spark-worker.service       loaded failed failed LSB: Spark worker

Note: systemctl list-units shows the services that are currently in memory.

From the manual:


list-units [PATTERN...]

List units that systemd currently has in memory. This includes units that are either referenced directly or through a dependency, units that are pinned by applications programmatically, or units that were active in the past and have failed. By default only units which are active, have pending jobs, or have failed are shown; this can be changed with option --all. If one or more PATTERNs are specified, only units matching one of them are shown. The units that are shown are additionally filtered by --type= and --state= if those options are specified.

When you run systemctl list-units, it only shows units that are currently loaded into memory. If a service hasn't been started or is completely inactive (not loaded, not running, and not triggered), it won't appear in this list unless you explicitly query for it.

To see all available units, even those not currently in memory, you can use systemctl list-unit-files --type=service. Here's the output on my Ubuntu machine:

# systemctl list-unit-files --type=service
UNIT FILE                              STATE           VENDOR PRESET
apparmor.service                       enabled         enabled      
apport-autoreport.service              static          -            
apport-forward@.service                static          -            
apport.service                         generated       -            
apt-daily-upgrade.service              static          -            
apt-daily.service                      static          -            
apt-news.service                       static          -            
autovt@.service                        alias           -            
blk-availability.service               enabled         enabled      
bolt.service                           static          -            
cloud-config.service                   enabled         enabled      
cloud-final.service                    enabled         enabled      
cloud-init-hotplugd.service            static          -            
cloud-init-local.service               enabled         enabled      
cloud-init.service                     enabled         enabled      
console-getty.service                  disabled        disabled     
console-setup.service                  enabled         enabled      
container-getty@.service               static          -            
cron.service                           enabled         enabled      
cryptdisks-early.service               masked          enabled      
cryptdisks.service                     masked          enabled      
dbus-org.freedesktop.hostname1.service alias           -            
dbus-org.freedesktop.locale1.service   alias           -            
dbus-org.freedesktop.login1.service    alias           -            
dbus-org.freedesktop.resolve1.service  alias           -            
dbus-org.freedesktop.timedate1.service alias           -            
dbus-org.freedesktop.timesync1.service alias           -            
dbus.service                           static          -            
debug-shell.service                    disabled        disabled     
dm-event.service                       static          -            
dmesg.service                          enabled         enabled      
dpkg-db-backup.service                 static          -            
e2scrub@.service                       static          -            
e2scrub_all.service                    static          -            
e2scrub_fail@.service                  static          -  
0

If you have perl and optionally unbuffer installed, a solution like this would give you pretty much what you want:

unbuffer systemctl status $service1 $service2 $service3 --no-pager --no-legend -n 0 | perl -ne 's{^((\033\S*)?\*\S*\s+(\S+))( - )?.*}{$1}s; print if m{^\s*Active:} || m{^\S*\*}'

You can leave out "unbuffer" if you don't have it installed (usually comes with expect), at the cost of the color output. Here is sample output, minus the color:

* puppet.service   Active: inactive (dead) since Mon 2025-04-14 13:34:13 EDT; 3min 7s ago
* sshd.service   Active: active (running) since Thu 2025-03-20 07:36:44 EDT; 3 weeks 4 days ago

It can technically be done in awk + sed instead, but it's a little cleaner in perl.

If you want to see all services, you can do this instead:

unbuffer systemctl status --all --no-pager --no-legend -n 0 | perl -ne 's{^((\033\S*)?\*\S*\s+(\S+))( - )?.*}{$1}s; print if m{^\s*Active:} || m{^\S*\*}'

Explanation:

  • The basic systemctl options are as others described: leave out the legend, disable the pager so it doesn't interfere, skip journal entries since we don't need them
  • The unbuffer wrapper fools most commands to act as if they're interactive even if they're outputting to a file or pipe. I won't go into why this works, but it's handy for enabling color, and for changing the buffer characteristics of programs from using large buffers to using line buffers. The latter is what gives the program its name.
  • The perl command changes the lines that start with asterisk and contain the service name and description to remove the description and remove the trailing newline. And it only prints the asterisk lines and the "Active:" lines, which get merged because the asterisk lines have the newline removed.
  • This approach only needs a single loop. But it's a little fragile in that in relies on details of how the underlying command produces output. That is subject to change.

Hope this helps!

Morty
  • 1