# bad-demo.-weight: 500;">service
[Unit]
Description=Bad demo
After=network-online.targt [Service]
Typ=oneshot
ExecStart=/usr/bin/not-a-real-binary
Restart=on-failure
# bad-demo.-weight: 500;">service
[Unit]
Description=Bad demo
After=network-online.targt [Service]
Typ=oneshot
ExecStart=/usr/bin/not-a-real-binary
Restart=on-failure
# bad-demo.-weight: 500;">service
[Unit]
Description=Bad demo
After=network-online.targt [Service]
Typ=oneshot
ExecStart=/usr/bin/not-a-real-binary
Restart=on-failure
systemd-analyze verify ./bad-demo.-weight: 500;">service
systemd-analyze verify ./bad-demo.-weight: 500;">service
systemd-analyze verify ./bad-demo.-weight: 500;">service
./bad-demo.-weight: 500;">service:3: Failed to add dependency on network-online.targt, ignoring: Invalid argument
./bad-demo.-weight: 500;">service:6: Unknown key 'Typ' in section [Service], ignoring.
bad-demo.-weight: 500;">service: Command /usr/bin/not-a-real-binary is not executable: No such file or directory
./bad-demo.-weight: 500;">service:3: Failed to add dependency on network-online.targt, ignoring: Invalid argument
./bad-demo.-weight: 500;">service:6: Unknown key 'Typ' in section [Service], ignoring.
bad-demo.-weight: 500;">service: Command /usr/bin/not-a-real-binary is not executable: No such file or directory
./bad-demo.-weight: 500;">service:3: Failed to add dependency on network-online.targt, ignoring: Invalid argument
./bad-demo.-weight: 500;">service:6: Unknown key 'Typ' in section [Service], ignoring.
bad-demo.-weight: 500;">service: Command /usr/bin/not-a-real-binary is not executable: No such file or directory
# demo-backup.-weight: 500;">service
[Unit]
Description=Demo backup job
Wants=network-online.target
After=network-online.target [Service]
Type=oneshot
ExecStart=/usr/bin/env bash -lc 'echo backing up; exit 0'
ProtectSystem=strict
ReadWritePaths=/var/backups
NoNewPrivileges=yes
# demo-backup.-weight: 500;">service
[Unit]
Description=Demo backup job
Wants=network-online.target
After=network-online.target [Service]
Type=oneshot
ExecStart=/usr/bin/env bash -lc 'echo backing up; exit 0'
ProtectSystem=strict
ReadWritePaths=/var/backups
NoNewPrivileges=yes
# demo-backup.-weight: 500;">service
[Unit]
Description=Demo backup job
Wants=network-online.target
After=network-online.target [Service]
Type=oneshot
ExecStart=/usr/bin/env bash -lc 'echo backing up; exit 0'
ProtectSystem=strict
ReadWritePaths=/var/backups
NoNewPrivileges=yes
# demo-backup.timer
[Unit]
Description=Run demo backup every night [Timer]
OnCalendar=03:15
Persistent=true
Unit=demo-backup.-weight: 500;">service [Install]
WantedBy=timers.target
# demo-backup.timer
[Unit]
Description=Run demo backup every night [Timer]
OnCalendar=03:15
Persistent=true
Unit=demo-backup.-weight: 500;">service [Install]
WantedBy=timers.target
# demo-backup.timer
[Unit]
Description=Run demo backup every night [Timer]
OnCalendar=03:15
Persistent=true
Unit=demo-backup.-weight: 500;">service [Install]
WantedBy=timers.target
systemd-analyze verify ./demo-backup.-weight: 500;">service ./demo-backup.timer
systemd-analyze verify ./demo-backup.-weight: 500;">service ./demo-backup.timer
systemd-analyze verify ./demo-backup.-weight: 500;">service ./demo-backup.timer
systemd-analyze verify ./myjob.-weight: 500;">service ./myjob.timer && \
-weight: 600;">sudo -weight: 500;">install -m 0644 ./myjob.-weight: 500;">service ./myjob.timer /etc/systemd/system/ && \
-weight: 600;">sudo -weight: 500;">systemctl daemon-reload && \
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable --now myjob.timer
systemd-analyze verify ./myjob.-weight: 500;">service ./myjob.timer && \
-weight: 600;">sudo -weight: 500;">install -m 0644 ./myjob.-weight: 500;">service ./myjob.timer /etc/systemd/system/ && \
-weight: 600;">sudo -weight: 500;">systemctl daemon-reload && \
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable --now myjob.timer
systemd-analyze verify ./myjob.-weight: 500;">service ./myjob.timer && \
-weight: 600;">sudo -weight: 500;">install -m 0644 ./myjob.-weight: 500;">service ./myjob.timer /etc/systemd/system/ && \
-weight: 600;">sudo -weight: 500;">systemctl daemon-reload && \
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable --now myjob.timer
-weight: 500;">systemctl -weight: 500;">status myjob.timer myjob.-weight: 500;">service --no-pager
journalctl -u myjob.-weight: 500;">service -u myjob.timer -b --no-pager
-weight: 500;">systemctl -weight: 500;">status myjob.timer myjob.-weight: 500;">service --no-pager
journalctl -u myjob.-weight: 500;">service -u myjob.timer -b --no-pager
-weight: 500;">systemctl -weight: 500;">status myjob.timer myjob.-weight: 500;">service --no-pager
journalctl -u myjob.-weight: 500;">service -u myjob.timer -b --no-pager
systemd-analyze verify --recursive-errors=yes ./myjob.-weight: 500;">service ./myjob.timer
systemd-analyze verify --recursive-errors=yes ./myjob.-weight: 500;">service ./myjob.timer
systemd-analyze verify --recursive-errors=yes ./myjob.-weight: 500;">service ./myjob.timer
pkgroot/
└── etc/systemd/system/ └── app.-weight: 500;">service
pkgroot/
└── etc/systemd/system/ └── app.-weight: 500;">service
pkgroot/
└── etc/systemd/system/ └── app.-weight: 500;">service
systemd-analyze verify --root="$PWD/pkgroot" app.-weight: 500;">service
systemd-analyze verify --root="$PWD/pkgroot" app.-weight: 500;">service
systemd-analyze verify --root="$PWD/pkgroot" app.-weight: 500;">service
systemd-analyze calendar '03:15'
-weight: 500;">systemctl -weight: 500;">start myjob.-weight: 500;">service
journalctl -u myjob.-weight: 500;">service -n 50 --no-pager
systemd-analyze calendar '03:15'
-weight: 500;">systemctl -weight: 500;">start myjob.-weight: 500;">service
journalctl -u myjob.-weight: 500;">service -n 50 --no-pager
systemd-analyze calendar '03:15'
-weight: 500;">systemctl -weight: 500;">start myjob.-weight: 500;">service
journalctl -u myjob.-weight: 500;">service -n 50 --no-pager
#!/usr/bin/env bash
set -euo pipefail units=( systemd/myjob.-weight: 500;">service systemd/myjob.timer
) systemd-analyze verify --recursive-errors=one "${units[@]}"
#!/usr/bin/env bash
set -euo pipefail units=( systemd/myjob.-weight: 500;">service systemd/myjob.timer
) systemd-analyze verify --recursive-errors=one "${units[@]}"
#!/usr/bin/env bash
set -euo pipefail units=( systemd/myjob.-weight: 500;">service systemd/myjob.timer
) systemd-analyze verify --recursive-errors=one "${units[@]}"
- name: Verify systemd units run: | systemd-analyze verify --recursive-errors=one \ systemd/myjob.-weight: 500;">service \ systemd/myjob.timer
- name: Verify systemd units run: | systemd-analyze verify --recursive-errors=one \ systemd/myjob.-weight: 500;">service \ systemd/myjob.timer
- name: Verify systemd units run: | systemd-analyze verify --recursive-errors=one \ systemd/myjob.-weight: 500;">service \ systemd/myjob.timer - validating unit files before reload or deploy
- catching unknown directives and bad dependency names
- verifying a -weight: 500;">service and its timer together
- making verification fail your CI job when warnings appear
- understanding what verify catches, and what it does not - unknown sections and directives
- missing dependencies required to -weight: 500;">start the unit
- Documentation= man pages that are not present
- commands in ExecStart= and similar directives that are missing or not executable - Write or -weight: 500;">update the unit files in a working directory.
- Run systemd-analyze verify against the -weight: 500;">service, timer, socket, or path units involved.
- Copy them into /etc/systemd/system/ only after they verify cleanly.
- Run -weight: 500;">systemctl daemon-reload.
- Start the unit and inspect logs. - yes: fail on warnings in the unit or any associated dependencies
- one: fail on warnings in the unit or its immediate dependencies
- no: fail only on warnings in the explicitly specified unit - your -weight: 500;">service logic is correct
- the command behaves correctly with real environment variables or credentials
- the -weight: 500;">service has all required runtime permissions
- the timer schedule is what you intended
- the -weight: 500;">service will stay healthy after startup - verify before -weight: 500;">install
- reload only after verify passes
- -weight: 500;">start the unit and inspect logs before calling it done - systemd-analyze(1) manual: https://www.freedesktop.org/software/systemd/man/latest/systemd-analyze.html
- Linux man page mirror for systemd-analyze(1): https://man7.org/linux/man-pages/man1/systemd-analyze.1.html
- systemd.unit(5) manual: https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html
- systemd.timer(5) manual: https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html
- -weight: 500;">systemctl(1) manual: https://www.freedesktop.org/software/systemd/man/latest/-weight: 500;">systemctl.html