sysadmin · difficulty ◆◆
systemctl — control systemd services
The one command that runs every service on a modern Linux box.
Your web server just died at 3am. The first command you type is systemctl status — and it tells you exactly what happened, when, and why. Here is how to read it like a pro.
AI-generated draft · reviewed and editedThis text was generated with AI as a first draft, then reviewed and edited by the author, who holds editorial responsibility for it.$ systemctlWhat it does
systemctl is the front door to systemd, the init system that boots and supervises every service on virtually all modern Linux distributions. It starts, stops, restarts, enables, disables, and inspects units — services, sockets, timers, mounts. When something is broken, systemctl status is where you start looking.
Why it matters
Before systemd, every distro had its own init scripts and its own way of managing services. systemctl standardized it: the same commands work on Ubuntu, Fedora, Debian, and Arch. It also gives you dependency tracking, automatic restarts, and a unified log view via journalctl. If you administer any Linux server, systemctl is the command you will type more than any other.
Unit files: cat, edit, and daemon-reload
When status is not enough, read the unit itself. `systemctl cat docker` prints the effective unit file, and if the unit has drop-in snippets it prints each of them first with the file path in a comment, so you can see which file a setting came from. To change something, use `systemctl edit <unit>`: it opens a drop-in override under /etc/systemd/system/<unit>.d/ instead of touching the vendor's file, which is what keeps your change alive across package upgrades. After any edit, run `systemctl daemon-reload` — systemd keeps unit files in memory and only rereads them when told to. Reloading the manager is not the same as reloading the service: `systemctl reload <unit>` asks the daemon to re-read its own configuration, and it only works if the unit defines ExecReload=. And when you want a service both enabled at boot and running now, `systemctl enable --now <unit>` does both in one step — enable on its own starts nothing.
Example
$ systemctl status docker● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
Active: active (running) since Wed 2026-08-19 07:06:55 CEST; 2 weeks 0 days ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 2295363 (dockerd)
Tasks: 355
Memory: 1.3G (peak: 7.4G swap: 120.4M swap peak: 252.0M)The Active line is the headline: active (running) since a date tells you it is up and when it started. Loaded shows whether it is enabled to start at boot.
$ systemctl is-active docker && systemctl is-enabled dockeractive
enabledis-active and is-enabled are script-friendly: they print one word and exit 0 on success, so you can chain them with && in cron jobs and health checks.
$ systemctl list-units --type=service --state=running UNIT LOAD ACTIVE SUB DESCRIPTION
bolt.service loaded active running Thunderbolt system service
containerd.service loaded active running containerd container runtime
cron.service loaded active running Regular background program processing daemon
dbus.service loaded active running D-Bus System Message Bus
docker.service loaded active running Docker Application Container Engine
fwupd.service loaded active running Firmware update daemon
getty@tty1.service loaded active running Getty on tty1Filter to exactly what you want: running services only. Add --no-pager to avoid the pager when scripting.
$ systemctl restart nginx$ systemctl restart nginx
$ systemctl is-active nginx
activerestart stops and starts a service in one step. No output on success — verify with is-active. This is the fix for a hung or misconfigured service.
$ systemctl list-timersNEXT LEFT LAST PASSED UNIT ACTIVATES
Wed 2026-09-02 09:10:00 CEST 8min Wed 2026-09-02 09:00:02 CEST 1min 30s ago sysstat-collect.timer sysstat-collect.service
Wed 2026-09-02 09:56:10 CEST 54min Wed 2026-09-02 08:58:06 CEST 3min 26s ago fwupd-refresh.timer fwupd-refresh.service
Wed 2026-09-02 11:12:43 CEST 2h 11min Tue 2026-09-01 03:40:53 CEST 1 day 5h ago plocate-updatedb.timer plocate-updatedb.servicelist-timers shows scheduled jobs (cron's modern replacement). NEXT and LEFT tell you when each will fire next.
Common flags
- status <unit>
- show whether a service is running, since when, and recent log lines
- start/stop/restart <unit>
- change a service's running state
- enable/disable <unit>
- set whether a service starts at boot
- is-active <unit>
- print active/inactive — script-friendly, exits 0 on active
- is-enabled <unit>
- print enabled/disabled — whether it starts at boot
- list-units
- list loaded units; filter with --type and --state
- list-timers
- show scheduled timer jobs and their next run times
- mask/unmask <unit>
- make a service impossible to start (hard disable)
History
Origin
systemd was created by Lennart Poettering at Red Hat and released on 30 March 2010. It entered Fedora as a non-default option in Fedora 14 in November 2010, and Fedora 15 made it the default init in May 2011 — the first major distribution to make that switch. Its name is a play on the Unix daemon convention — the 'd' suffix — applied to the system itself. It replaced the SysV init scripts that had been the standard since the 1980s, and it was deeply controversial: the 'init wars' between systemd and its critics are still a live topic in the Linux community.
Fun fact
systemd does far more than start services. It also manages sockets, timers, device nodes, mount points, and even the login session. The name is a pun: it is the daemon that manages the system, so it is literally the 'system daemon' — systemd.
Fun facts
Pros & cons
pros
- + One consistent interface across every major distro
- + Dependency tracking and automatic restarts built in
- + Unified with journalctl for logs — status shows recent output directly
- + Script-friendly is-active/is-enabled for automation
cons
- − Steep learning curve — dozens of subcommands and unit types
- − Controversial; some admins still prefer the simpler SysV model
- − Overkill for trivial tasks that a shell script handled fine
- − Unit file syntax is finicky and easy to get wrong
Takeaways
- 1Start debugging with `systemctl status <service>` — it shows state, uptime, and recent logs in one place
- 2Use `systemctl restart <service>` to fix a hung or misconfigured service
- 3Chain `systemctl is-active` in scripts — it exits 0 on active
- 4enable starts at boot; start runs now — they are separate
- 5Check scheduled jobs with `systemctl list-timers`, not just cron
