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 statusforExecStartPreorExecStartfailures—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
startcommand.
Unmask with:systemctl unmask bad.service - Note:
systemctl --failedquickly 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.
