Commands and Management
By the end of this lesson you will be fluent in every systemctl and journalctl command needed to manage .path units — from creation to cleanup, including user-level units, path-specific debugging, and bulk operations.
Essential Command Workflow
Every time you create or modify a path unit, follow this sequence:
# 1. Edit the unit file
sudo nano /etc/systemd/system/mytask.path
# 2. Tell systemd to re-read unit files
sudo systemctl daemon-reload
# 3. Enable on boot and start now
sudo systemctl enable --now mytask.path
# 4. Verify the watch is active
systemctl status mytask.path --no-pager
# 5. Trigger the event (e.g., drop a file)
touch /path/to/watched/file
# 6. Check logs
journalctl -u mytask.service -n 20 --no-pager
systemctl — Path Unit Management
Starting and Stopping
| Command | Description |
|---|---|
sudo systemctl start mytask.path | Start the filesystem watch immediately |
sudo systemctl stop mytask.path | Stop the watch (does not disable on boot) |
sudo systemctl restart mytask.path | Stop and restart the watch |
sudo systemctl reload-or-restart mytask.path | Reload if supported, otherwise restart |
# Start a watcher
sudo systemctl start process-drop.path
# Stop it temporarily (it will start again on next boot if enabled)
sudo systemctl stop process-drop.path
# Restart after changing the unit file
sudo systemctl daemon-reload
sudo systemctl restart process-drop.path
Enabling and Disabling
| Command | Description |
|---|---|
sudo systemctl enable mytask.path | Enable on boot (creates symlinks, does not start) |
sudo systemctl enable --now mytask.path | Enable on boot AND start immediately |
sudo systemctl disable mytask.path | Disable on boot (removes symlinks, does not stop) |
sudo systemctl disable --now mytask.path | Disable on boot AND stop immediately |
.path, NOT the .serviceA common mistake is enabling the .service directly. This would run it once at boot — not what you want. Always enable the .path unit:
# ✅ Correct
sudo systemctl enable --now mytask.path
# ❌ Wrong — runs the service once at boot, no filesystem watching
sudo systemctl enable --now mytask.service
Checking Status
| Command | Description |
|---|---|
systemctl status mytask.path | Watch state, directive, last trigger time, enabled state |
systemctl status mytask.service | Exit code, process output, runtime, failure reason |
systemctl status mytask.path --no-pager | Same, without piping through a pager |
systemctl show mytask.path | Machine-readable properties (for scripting) |
systemctl is-active mytask.path | Returns active or inactive |
systemctl is-enabled mytask.path | Returns enabled or disabled |
# Check the watcher state
systemctl status process-drop.path --no-pager
# Check what the triggered service did
systemctl status process-drop.service --no-pager
# Quick check in scripts
if systemctl is-active --quiet process-drop.path; then
echo "Watcher is running"
fi
● process-drop.path - Watch /var/www/drop for incoming files
Loaded: loaded (/etc/systemd/system/process-drop.path; enabled; preset: enabled)
Active: active (waiting) since Mon 2026-03-02 03:06:00 UTC; 1h ago
Triggers: ● process-drop.service
Watch: /var/www/drop (DirectoryNotEmpty)
Reading Status Output
| Field | Meaning |
|---|---|
Loaded: loaded (…; enabled) | Unit file is valid and enabled on boot |
Active: active (waiting) | Watch is registered and waiting for events |
Active: inactive (dead) | Watch is stopped |
Triggers: ● process-drop.service | Which service this path unit activates |
Watch: /var/www/drop (DirectoryNotEmpty) | What path and directive is being used |
Reloading Daemon
| Command | Description |
|---|---|
sudo systemctl daemon-reload | Re-read ALL unit files from disk |
sudo systemctl daemon-reexec | Re-execute the systemd manager itself (rare) |
If you edit a unit file and forget to run daemon-reload, systemd will use the old version of the file. This is the #1 beginner mistake.
# After ANY edit to a unit file:
sudo systemctl daemon-reload
systemctl — Listing and Discovery
List Path Units
# List all path units (active and inactive)
systemctl list-units --type=path --all
# List only active path units
systemctl list-units --type=path
# List enabled path units (will start on boot)
systemctl list-unit-files --type=path --state=enabled
UNIT LOAD ACTIVE SUB DESCRIPTION
cert-watcher.path loaded active waiting Watch for renewed TLS certificates
csv-import.path loaded active waiting Watch for incoming CSV imports
deploy-trigger.path loaded active waiting Watch for deploy signal file
process-drop.path loaded active waiting Watch /var/www/drop for incoming files
Show Unit File Location
# Show where the unit file is stored
systemctl show -p FragmentPath process-drop.path
# Show the full unit file content
systemctl cat process-drop.path
systemctl cat process-drop.service
List Dependencies
# Show what depends on this unit
systemctl list-dependencies process-drop.path
# Show what this unit triggers
systemctl show -p Triggers process-drop.path
journalctl — Log Management
Viewing Service Logs
The .path unit doesn't produce much log output — the real logs come from the .service unit.
| Command | Description |
|---|---|
journalctl -u mytask.service | All logs from the service |
journalctl -u mytask.service -n 50 | Last 50 lines |
journalctl -u mytask.service -f | Follow live output (like tail -f) |
journalctl -u mytask.service --since "1 hour ago" | Logs from the last hour |
journalctl -u mytask.service --since today | Today's logs |
journalctl -u mytask.service --since "2026-03-01" --until "2026-03-02" | Date range |
journalctl -u mytask.service -o json-pretty | JSON format (for parsing) |
journalctl -u mytask.service -p err | Only error-level messages |
# Follow live output while testing
journalctl -u process-drop.service -f
# Check if there were any errors today
journalctl -u process-drop.service --since today -p err --no-pager
# View the last 3 invocations
journalctl -u process-drop.service -n 30 --no-pager
Viewing Path Unit Logs
# See when the path unit was started, stopped, or triggered
journalctl -u process-drop.path --since today --no-pager
Mar 02 03:06:00 vps systemd[1]: Started process-drop.path - Watch /var/www/drop for incoming files.
Mar 02 03:06:05 vps systemd[1]: process-drop.path: Triggering process-drop.service.
Mar 02 03:07:12 vps systemd[1]: process-drop.path: Triggering process-drop.service.
Combined View
# See both path and service logs together, interleaved by time
journalctl -u process-drop.path -u process-drop.service --since today --no-pager
Log Priority Levels
| Level | Flag | Meaning |
|---|---|---|
| Emergency | -p emerg | System is unusable |
| Alert | -p alert | Immediate action required |
| Critical | -p crit | Critical conditions |
| Error | -p err | Error conditions |
| Warning | -p warning | Warning conditions |
| Notice | -p notice | Normal but significant |
| Info | -p info | Informational |
| Debug | -p debug | Debug-level messages |
systemd-analyze — Validation and Debugging
Verify Unit Files
Before deploying a new unit, validate the syntax:
# Verify a path unit
sudo systemd-analyze verify /etc/systemd/system/process-drop.path
# Verify a service unit
sudo systemd-analyze verify /etc/systemd/system/process-drop.service
# Verify both at once
sudo systemd-analyze verify /etc/systemd/system/process-drop.{path,service}
If there are no errors, the command produces no output. Errors are printed to stderr:
/etc/systemd/system/process-drop.path:5: Unknown key 'Watchh' in section 'Path'
Check Boot Impact
# See how path units affect boot time
systemd-analyze blame | grep path
# Show the critical chain
systemd-analyze critical-chain paths.target
Security Analysis
# Audit the security exposure of your service
systemd-analyze security process-drop.service
This produces a security score (0.0 = fully sandboxed, 10.0 = no sandboxing):
NAME DESCRIPTION EXPOSURE
✗ PrivateDevices= Service has access to hardware devices 0.2
✗ PrivateTmp= Service has access to other software's 0.1
...
→ Overall exposure level for process-drop.service: 7.2 MEDIUM
User Unit Management
User units run without root privileges and are managed with the --user flag.
User Unit Commands
| Command | Description |
|---|---|
systemctl --user daemon-reload | Reload user unit files |
systemctl --user enable --now mytask.path | Enable and start a user path unit |
systemctl --user disable --now mytask.path | Disable and stop a user path unit |
systemctl --user status mytask.path | Check status of a user path unit |
systemctl --user list-units --type=path | List all user path units |
journalctl --user -u mytask.service | View user service logs |
# Create user unit directory
mkdir -p ~/.config/systemd/user/
# Place your units in ~/.config/systemd/user/
# Reload and enable
systemctl --user daemon-reload
systemctl --user enable --now my-watcher.path
# Check
systemctl --user status my-watcher.path
Persistence After Logout
By default, user units stop when you log out. To keep them running:
# Enable linger for the current user
sudo loginctl enable-linger "$USER"
# Check linger status
loginctl show-user "$USER" | grep Linger
# Disable linger
sudo loginctl disable-linger "$USER"
Bulk Operations
Enable All Path Units at Once
# Enable and start all path units in a directory
for unit in /etc/systemd/system/*.path; do
name=$(basename "$unit")
sudo systemctl enable --now "$name"
done
Check All Path Units
# Quick health check of all path units
systemctl list-units --type=path --all --no-pager --no-legend | while read -r unit rest; do
echo "=== $unit ==="
systemctl status "$unit" --no-pager 2>/dev/null | head -5
echo
done
Stop and Remove a Path Unit
# Full cleanup procedure
sudo systemctl disable --now process-drop.path
sudo rm /etc/systemd/system/process-drop.path
sudo rm /etc/systemd/system/process-drop.service
sudo systemctl daemon-reload
sudo systemctl reset-failed # Clear failed state if any
Quick Command Reference
| Task | Command |
|---|---|
| Reload unit files | sudo systemctl daemon-reload |
| Start watcher | sudo systemctl start mytask.path |
| Stop watcher | sudo systemctl stop mytask.path |
| Enable on boot + start | sudo systemctl enable --now mytask.path |
| Disable + stop | sudo systemctl disable --now mytask.path |
| Check watcher status | systemctl status mytask.path --no-pager |
| Check service result | systemctl status mytask.service --no-pager |
| Follow live service logs | journalctl -u mytask.service -f |
| Last N log lines | journalctl -u mytask.service -n 50 |
| Logs since a time | journalctl -u mytask.service --since "1 hour ago" |
| Verify unit syntax | sudo systemd-analyze verify mytask.path |
| List all path units | systemctl list-units --type=path --all |
| Show unit file content | systemctl cat mytask.path |
| Show unit file path | systemctl show -p FragmentPath mytask.path |
| Restart watcher | sudo systemctl restart mytask.path |
| Run service manually | sudo systemctl start mytask.service |
| Security audit | systemd-analyze security mytask.service |
Key Takeaways
- Always run
daemon-reloadafter any unit file edit. - Enable the
.pathunit, not the.service. - Check both
.pathstatus (watch state) and.servicestatus (execution result). - Use
journalctl -u service -ffor live debugging. - Use
systemd-analyze verifybefore deploying new units. - User units need
loginctl enable-lingerfor persistence after logout.
What's Next
- Practical Examples — 20 complete, copy-paste-ready examples covering every watch directive.