Skip to content

Everyday systemctl

Scope: the handful of verbs that cover daily life, and the two distinctions that cause real confusion: start vs. enable, and status's exit codes.

The verbs

sudo systemctl start mere-demo.service
sudo systemctl stop mere-demo.service
sudo systemctl restart mere-demo.service
systemctl status mere-demo.service
systemctl is-active mere-demo.service
  • start / stop — act now.
  • restart — stop (if running) then start. Also reload for services that can re-read config without restarting (reload only works if the unit defines ExecReload; otherwise it errors and you wanted restart anyway).
  • status — the report card: loaded state, active state, main PID, memory/CPU so far, and the last few journal lines. Real output from the lab:
● mere-demo.service - Mere Mortals demo heartbeat service
     Loaded: loaded (/etc/systemd/system/mere-demo.service; disabled; preset: enabled)
     Active: active (running) since Fri 2026-10-16 18:31:27 CDT; 3s ago
   Main PID: 16299 (mere-demo.sh)
        CPU: 6ms
     CGroup: /system.slice/mere-demo.service
             ├─16299 /bin/bash /usr/local/bin/mere-demo.sh
             └─16302 sleep 2

The CGroup tree is worth a look: systemd shows the whole process tree it supervises — here, the script and the sleep it spawned. That tree is why systemd can stop a service completely: it signals the group, not just the main PID.

start ≠ enable

The distinction that confuses every newcomer, because two different questions are being answered:

  • start — "run it now?" A started service stops at shutdown and does not come back at boot.
  • enable — "run it at boot?" Enabling creates a symlink and changes nothing about right now:
sudo systemctl enable mere-demo.service
Created symlink /etc/systemd/system/multi-user.target.wants/mere-demo.service → /etc/systemd/system/mere-demo.service.

That symlink is the entire mechanism: multi-user.target "wants" the unit (there's the WantedBy= from the [Install] section). is-enabled reports enabled; disable removes the symlink. The everyday compound is enable --now, which does both. A service can be in any combination — running-but-not-enabled (won't survive reboot), enabled-but-not-running (will start next boot) — and status's Loaded: line tells you which.

is-active and exit codes, for scripts

systemctl is-active mere-demo.service
active

After stopping it, the same command prints inactive and exits with code 3. Scripts (and monitoring) depend on that code; humans depend on the word. The full is-active vocabulary: active, inactive, failed, activating, deactivating. Learn failed on sight — it's the subject of chapters 6 and 11.

Look without touching

systemctl show mere-demo.service -p MainPID -p Restart
Restart=on-failure
MainPID=16299

show dumps every property systemd holds for the unit — dozens. With -p you pick the ones you need; scripts love it because the format never changes.