systemd Cheatsheet
systemctl Basics
Use this systemd reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Looking at State
systemctl with no arguments lists every unit systemd currently has in memory. In practice you always narrow it.
| Command | Shows |
|---|---|
systemctl status nginx | State, main PID, cgroup, last 10 log lines |
systemctl status | Whole-system state and the unit tree |
systemctl is-active nginx | active / inactive, exit code 0 when active |
systemctl is-enabled nginx | enabled / disabled / masked / static |
systemctl is-failed nginx | failed, exit 0 when the unit failed |
systemctl list-units --type=service | Loaded services |
systemctl list-units --state=failed | Everything broken right now |
systemctl --failed | Shorthand for the line above |
systemctl list-unit-files | Installed unit files and their enablement |
systemctl list-dependencies nginx | Recursive dependency tree |
systemctl list-timers --all | Timers with next and last elapse |
systemctl list-sockets | Socket units by listening address |
systemctl show nginx | Every resolved property, machine readable |
The .service suffix is optional in every command. systemctl status ngin* accepts globs.
Start, Stop, Restart, Reload
systemctl start nginx systemctl stop nginx systemctl restart nginx # stop then start, drops connections systemctl reload nginx # only if the unit defines ExecReload= systemctl reload-or-restart nginx # reload when supported, else restart systemctl try-restart nginx # restart only if already running systemctl kill nginx # send SIGTERM to the cgroup systemctl kill -s SIGKILL nginx # or a specific signal
reload fails outright when the unit file has no ExecReload=. reload-or-restart is the safe scripted choice. All of these block until the job finishes unless you pass --no-block.
Enable and Disable
enable is about boot, start is about now. They are independent, and forgetting that is the most common systemd surprise.
systemctl enable nginx # create the [Install] symlinks systemctl enable --now nginx # enable and start in one step systemctl disable --now nginx # disable and stop systemctl reenable nginx # remove then recreate the symlinks systemctl preset nginx # reset to the distro preset policy
enable only works when the unit has an [Install] section. Units without one report static, which means they are pulled in by another unit rather than enabled directly.
daemon-reload vs restart vs reload
Three different things that people mix up constantly.
| Command | Effect |
|---|---|
systemctl daemon-reload | Re-read unit files from disk into systemd |
systemctl restart foo | Stop and start the foo process |
systemctl reload foo | Ask the foo process to re-read its own config |
Edit a unit file, then daemon-reload, then restart. Without the reload systemd keeps running the old unit definition and your change silently does nothing. systemctl status warns with "changed on disk" when you forget.
systemctl daemon-reexec re-executes the systemd manager itself, serializing and restoring state. You need it after a systemd package upgrade, almost never otherwise.
Masking, Linking, Reverting
systemctl mask apache2 # symlink the unit to /dev/null, unstartable systemctl unmask apache2 systemctl link /opt/app/app.service # pull an out-of-tree file into the path systemctl revert nginx # delete drop-ins and local overrides systemctl set-property nginx MemoryMax=1G # persistent systemctl set-property --runtime nginx CPUQuota=50% # until reboot
mask is stronger than disable. A disabled unit still starts when another unit pulls it in as a dependency, a masked one cannot start at all. revert throws away everything under /etc/systemd/system/foo.service.d/ and any /etc copy of the file, returning you to the packaged version.
Scoping and Remote Hosts
Every command above takes a manager scope. The default is --system.
systemctl --user status syncthing # your per-user manager systemctl --global enable foo.service # default for all future users systemctl -H deploy@web1 status nginx # over SSH systemctl -M mycontainer list-units # inside a machined container systemctl --no-pager --plain list-units --type=timer
--no-pager and --plain matter in scripts, because interactive output is paged and decorated with tree glyphs by default. SYSTEMD_COLORS=0 strips ANSI codes.