Units and state

Find unit files and overrides

Locate vendor units and local drop-ins without editing package-owned files in place.

Unit files live in more than one directory, and the directory tells you who owns the file.

Packages install their unit files under /usr/lib/systemd/system or /lib/systemd/system. On Debian and Ubuntu those two are the same directory. Treat everything in there as vendor property.

Your own changes belong under /etc/systemd/system. Anything in that directory wins over the vendor copy.

The classic mistake is editing the vendor file in place. It works. Then the next package upgrade replaces the file, and your change is gone with no warning. I have seen this cost people hours.

See the effective configuration

systemctl cat shows every fragment systemd combined for a unit, and where each fragment came from:

systemctl cat ssh.service
# /usr/lib/systemd/system/ssh.service
[Unit]
Description=OpenBSD Secure Shell server
...
# /etc/systemd/system/ssh.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/sbin/sshd -D -p 2222

The second block is a drop-in: a small file that overrides only the settings it names. The vendor unit stays untouched. The local difference is explicit, and anyone reading the output can see it.

Create a drop-in with systemctl edit

You could create that directory and file by hand. Don’t. systemctl edit opens an editor on the right file and creates it if needed:

sudo systemctl edit ssh.service

It writes to /etc/systemd/system/ssh.service.d/override.conf and runs daemon-reload for you when you save.

There is also systemctl edit --full. That copies the whole unit into /etc/systemd/system, so your copy replaces the vendor file completely. You rarely want that. A full copy stops receiving vendor fixes, while a drop-in keeps them.

The ExecStart gotcha

List settings like ExecStart= append rather than replace. If your drop-in only adds a new ExecStart=, systemd now sees two of them and complains that the service has two ExecStart= lines.

To change the command you must clear it first with an empty assignment, then set the new value. That is exactly what the override above does:

[Service]
ExecStart=
ExecStart=/usr/sbin/sshd -D -p 2222

The empty line is not a typo. It is the reset.

Audit a whole machine

When you inherit a server, you want to know what someone changed. systemd-delta lists every unit that differs from its vendor version:

systemd-delta

Each line tells you whether the change is a drop-in ([EXTENDED]), a full override ([OVERRIDDEN]), or a masked unit. It is the quickest way to find surprises.

Try this on your own server. Run systemctl cat ssh.service and read where each fragment comes from. Then open sudo systemctl edit ssh.service, note the target path in the editor comment, and quit without saving.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →