How to List Services in Linux
Misconfigured or malfunctioning services cripple infrastructure fast. Knowing which daemons are up, which are enabled at boot, and which have failed is fundamental—regardless of whether the system runs Ubuntu 22.04 (systemd), Debian 7 (SysVinit), or some Frankenstein hybrid in production.
Understand: What "Services" Means in Practice
In Linux, "services" are long-running background processes—database engines, SSH daemons, monitoring agents. Most are started via the system init daemon; some are socket-activated, others started manually.
Modern Systems: systemd (systemctl
)
List All Service Unit Files
See everything present, regardless of whether it's enabled/running:
systemctl list-unit-files --type=service
This lists service units like:
nginx.service enabled
fail2ban.service enabled
app-migrator.service disabled
cups-browsed.service disabled
Note: masked
means the service is explicitly blocked from starting, often to avoid accidental activation.
View Only Running Services
For ongoing troubleshooting or resource usage checks:
systemctl list-units --type=service --state=running
Provides:
postgresql.service loaded active running PostgreSQL RDBMS
sshd.service loaded active running OpenSSH server daemon
Expect transient *.service
units for short-lived ones (e.g., systemd-update-utmp-runlevel.service
).
Inspect a Specific Service
systemctl status nginx.service
Returns state, cgroup, logs, and exit code. Look for lines like:
Active: failed (Result: exit-code) since ...
Main PID: 1023 (code=exited, status=1/FAILURE)
Gotcha
If troubleshooting why something isn't enabled at boot, use:
systemctl is-enabled yourservice.service
This avoids misreading a deactivated service as simply "inactive".
SysVinit / Legacy Systems
Enumerate All Services
service --status-all
Outputs:
[ + ] ssh
[ - ] rsync
[ ? ] httpd
[ + ]
= running, [ - ]
= stopped, [ ? ]
= unknown/unclear status.
Status of a Single Service
service ssh status
Older Debian/Ubuntu systems might output very limited information if the LSB (Linux Standard Base) script lacks status support.
Non-obvious tip
On certain distributions, /etc/init.d/yourservice status
gives more detail. However, some init scripts don’t implement the status
action—returns code 3.
RHEL/CentOS Extras: chkconfig
For static runlevel configuration (esp. RHEL 6.x and CentOS 6.x):
chkconfig --list
Gives a matrix of runlevels vs. enabled state (on
/off
). Useful for verifying startup order after legacy migrations.
Ad Hoc: Process Lists
Sometimes you just want to check if a rogue daemon is alive, regardless of the init system:
ps aux | grep [n]ginx
This filters out the grep process itself and shows matching processes. Pair with pgrep
for a cleaner approach:
pgrep -fl nginx
Common Scenarios—What Fails and Why
- Service appears enabled but isn't running: Check
systemctl status
forExecStartPre
orExecStart
failures—commonly permissions or missing directory. - Old init scripts after systemd migration: Check
/lib/systemd/system-generators/
for compatibility issues. - Masked services: They won’t start—even if you issue a
start
command.
Unmask with:systemctl unmask bad.service
- Note:
systemctl --failed
quickly lists units that have failed startup—essential for post-reboot analysis.
Quick Reference Table
What | Command |
---|---|
List all installed services (systemd) | systemctl list-unit-files --type=service |
List running services (systemd) | systemctl list-units --type=service --state=running |
Check if a service is enabled | systemctl is-enabled <service>.service |
Service status (SysVinit) | service <name> status |
List all legacy SysVinit services | service --status-all |
Runlevel/service matrix (RHEL/CentOS) | chkconfig --list |
Show only failed services (systemd) | systemctl --failed |
Summary
Service visibility isn’t perfect—especially with mish-mashed environments or half-migrated init setups. Confirm the init system before running commands. Whenever possible, combine systemctl list-unit-files
with real process listings (ps
, pgrep
) and journal logs (journalctl -u servicename
) for the clearest operational picture. Don't trust default service statuses in containers—PID 1 could be the service itself with no init system at all. If you care about runtime state automation, wire these queries into your monitoring.
Side note:
There are third-party tools like htop
, monit
, and GUIs for service management. Not covered here—they add complexity, not always clarity. Stick with the shell for critical triage.