LFCS 61 ๐ง systemd โ Managing Services
The LFCS exam tests systemd at the operational level: can you start a service, make it persist across reboots, verify its status, and read its logs? The commands are not complicated individually, but the exam is performance-based on a live system, and the most common failure is not a wrong commandโit is a command that works in the current session but does not survive a reboot. The systemctl enable versus systemctl start distinction is the single most tested concept in this domain, and the --now flag that combines them exists precisely because forgetting the enable step is the classic trap .
systemd organizes resources into units, and the service unit is the type that manages daemons. A service unit’s configuration file ends in .service and lives in directories like /usr/lib/systemd/system for package-installed units or /etc/systemd/system for administrator-created ones . The systemctl command is the interface: it starts, stops, enables, disables, and inspects units. The journalctl command reads the logs that systemd’s journal collects, and it filters by unit with the -u flag.
This chapter covers the service unit lifecycle, the enable/start distinction and the --now shorthand, status inspection and log reading, custom unit file creation, and the exam traps that turn a working command into a failed task. It assumes a running systemd-based Linux system and familiarity with basic command-line operations.
Key point: start runs a service now; enable makes it start at boot. The exam grader reboots the machine, so a service that was started but not enabled fails the task. systemctl enable --now <service> does both in one command, and it is the correct answer whenever the task says “start automatically at boot and start now.”
Why systemd service management is an exam domain
The exam is performance-based, not multiple-choice. The LFCS tests on a live system, and service configuration is weighted at roughly 20% of the exam alongside essential commands . A candidate who knows the commands but does not verify persistence will pass the command execution and fail the task. The exam scenarios are written to test operational judgment, not memorization: “A service should start automatically at boot and start now” is a scenario that distinguishes candidates who understand the enable/start distinction from those who do not .
The enable/start distinction is the primary trap. systemctl start nginx starts the service in the current session. It does not create the symlinks that cause systemd to start the service during boot. systemctl enable nginx creates those symlinks but does not start the service. The exam grader reboots the machine after the candidate finishes. A service that was started but not enabled is not running after the reboot, and the task fails . The --now flag exists to prevent this exact error: systemctl enable --now nginx enables and starts in one command .
Logs are part of the service lifecycle. When a service fails to start, the status output shows the last few log lines, but the full journal requires journalctl -u <service>. The -f flag follows new output, and -n <count> limits the number of lines. The exam tests the ability to diagnose why a service failed, not just whether it is running .
Custom unit files test understanding of the configuration model. A task may ask the candidate to configure an application as a service. This requires creating a .service file in /etc/systemd/system, defining the [Unit], [Service], and [Install] sections, running systemctl daemon-reload, and then enabling and starting the service. The [Install] section with WantedBy=multi-user.target is what makes enable work; without it, the service cannot be enabled .
The trade-off. systemd’s model is more verbose than the legacy service command. A single systemctl enable --now nginx replaces two separate commands and a symlink check. The verbosity is the price of the dependency management and parallel startup that systemd provides. The exam tests the verbosity because that is what production systems use.
a. The service lifecycle: start, stop, restart, reload
The basic service operations are direct: systemctl start <service> starts a stopped service, systemctl stop <service> stops a running one, and systemctl restart <service> stops and starts. systemctl reload <service> asks the service to reload its configuration without a full restart, but this only works if the service supports it; a service that does not support reload will return an error or ignore the command .
# Start the nginx service now.
sudo systemctl start nginx
# Stop it.
sudo systemctl stop nginx
# Restart: stop and start, applying configuration changes.
sudo systemctl restart nginx
# Reload: re-read configuration without dropping connections,
# if the service supports it.
sudo systemctl reload nginx
The condrestart (conditional restart) command restarts a service only if it is currently running. This is safer in scripts where the service may or may not be active, because it does not start a stopped service as a side effect. try-restart is an alias for the same behavior .
systemctl status <service> is the inspection command. It shows the service’s loaded state, active state, main PID, and the most recent log lines. The output distinguishes between active (running), inactive (dead), and failed. A service that exited with a non-zero status shows failed and the exit code .
# Check status: active state, PID, recent logs.
systemctl status nginx
The status output is a summary. For the full journal, journalctl -u nginx shows all log entries for the unit, and journalctl -u nginx -f follows new entries in real time. The -n 50 flag limits to the last 50 lines .
b. Enable and disable: persistence across reboots
systemctl enable <service> creates the symbolic links that cause systemd to start the service when the system reaches the target specified in the unit’s [Install] section. It does not start the service in the current session. systemctl disable <service> removes those symlinks. The is-enabled command reports whether the symlinks exist, and is-active reports whether the service is currently running .
# Enable at boot and start now, in one command.
sudo systemctl enable --now nginx
# Verify both states.
systemctl is-enabled nginx # enabled
systemctl is-active nginx # active
The --now flag is the exam-safe pattern. When a task says “ensure the service starts automatically at boot and is running now,” enable --now is the command that satisfies both requirements atomically. Using enable and start as separate commands works, but the combined form is less error-prone and directly maps to the task description .
The disable command does not stop a running service. A service can be running but disabled, or stopped but enabled. The two states are independent: enable controls boot behavior, start controls current behavior. The exam may test this independence by asking for a service that is running but not enabled, or enabled but not running.
Masking is a stronger form of disabling. systemctl mask <service> creates a symlink to /dev/null, preventing the service from being started at allโeven manually, and even as a dependency of another service. unmask reverses it. This is used when a service must be prevented from starting for security or policy reasons, not merely disabled at boot.
c. Creating a custom service unit
A custom service unit is a file in /etc/systemd/system/ with a .service extension. The minimal unit has three sections: [Unit] for metadata and dependencies, [Service] for the execution command and restart policy, and [Install] for the boot target that enable uses .
# /etc/systemd/system/my_app.service
[Unit]
Description=My Python Web Application
After=network.target
[Service]
ExecStart=/usr/bin/python3 /opt/code/my_app.py
Restart=always
User=appuser
[Install]
WantedBy=multi-user.target
ExecStart is the command that runs the service. Restart=always configures systemd to restart the process if it exits, which provides basic supervision. User=appuser runs the service as a non-root user. The After=network.target directive in [Unit] ensures the service starts after networking is available, which is important for applications that bind to a network port .
After creating or modifying a unit file, systemctl daemon-reload is required. systemd caches unit file contents, and it does not notice changes until the cache is refreshed. Without daemon-reload, systemctl start uses the old configuration, and the new service may fail with a “unit not found” error even though the file exists .
# Reload systemd's unit cache after creating or editing a unit.
sudo systemctl daemon-reload
# Enable and start the custom service.
sudo systemctl enable --now my_app
# Verify.
systemctl status my_app
The [Install] section is what makes enable possible. WantedBy=multi-user.target tells systemd that when the system reaches the multi-user target (the normal non-graphical boot state), it should start this service. Without an [Install] section, the service can be started manually but cannot be enabled, and the systemctl enable command returns an error .
Complete Example Session
# ============================================
# PART 1: START AND VERIFY
# ============================================
# Start the service now.
sudo systemctl start nginx
# Verify it is running.
systemctl is-active nginx # active
systemctl status nginx # shows PID and recent logs
# ============================================
# PART 2: THE ENABLE TRAP
# ============================================
# This starts nginx but does NOT survive a reboot.
sudo systemctl start nginx
# This makes it survive a reboot but does NOT start it now.
sudo systemctl enable nginx
# This does both, and is the exam-safe answer.
sudo systemctl enable --now nginx
# ============================================
# PART 3: STOP AND DISABLE
# ============================================
# Stop the running service.
sudo systemctl stop nginx
# Prevent it from starting at boot.
sudo systemctl disable nginx
# Verify both states.
systemctl is-active nginx # inactive
systemctl is-enabled nginx # disabled
# ============================================
# PART 4: LOGS
# ============================================
# View all journal entries for the unit.
journalctl -u nginx
# Follow new entries in real time.
journalctl -u nginx -f
# Last 50 lines plus follow.
journalctl -u nginx -n 50 -f
# ============================================
# PART 5: CREATE A CUSTOM SERVICE
# ============================================
# Create the unit file.
sudo tee /etc/systemd/system/my_app.service <<'EOF'
[Unit]
Description=My Application
After=network.target
[Service]
ExecStart=/usr/bin/python3 /opt/code/my_app.py
Restart=always
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd to pick up the new unit.
sudo systemctl daemon-reload
# Enable and start.
sudo systemctl enable --now my_app
# Verify.
systemctl status my_app
# ============================================
# PART 6: EDIT AN EXISTING UNIT SAFELY
# ============================================
# Use systemctl edit for drop-in overrides.
# Do not edit files in /usr/lib/systemd/system directly.
sudo systemctl edit my_app
# The editor opens a drop-in file at:
# /etc/systemd/system/my_app.service.d/override.conf
# Add or override directives, save, then reload.
sudo systemctl daemon-reload
sudo systemctl restart my_app
# ============================================
# PART 7: TROUBLESHOOT A FAILED SERVICE
# ============================================
# Check status for exit code and recent logs.
systemctl status my_app
# Read full journal.
journalctl -u my_app -n 100
# Common causes:
# - Wrong path in ExecStart
# - Missing User if service needs specific permissions
# - No [Install] section (cannot enable)
# - daemon-reload not run after creating unit
# ============================================
# PART 8: LIST SERVICES
# ============================================
# List running services.
systemctl list-units --type=service
# List all installed unit files, enabled or not.
systemctl list-unit-files
# Find failed units.
systemctl --failed
# ============================================
# PART 9: MASK TO PREVENT START
# ============================================
# Disable is not enough if the service is pulled in
# as a dependency. Mask prevents all starts.
sudo systemctl mask nginx
# Unmask to restore.
sudo systemctl unmask nginx
# ============================================
# PART 10: THE EXAM CHECKLIST
# ============================================
# For any service task, verify:
# 1. systemctl is-active <service> โ active
# 2. systemctl is-enabled <service> โ enabled
# 3. If custom unit: daemon-reload was run
# 4. If service fails: journalctl -u <service>
# The grader reboots. Enabled is not optional.
Quick Reference
Service Control Commands
| Command | Effect | Survives Reboot |
|---|---|---|
systemctl start <svc> | Start now | No |
systemctl stop <svc> | Stop now | No |
systemctl restart <svc> | Stop and start | No |
systemctl reload <svc> | Reload config (if supported) | No |
systemctl enable <svc> | Start at boot | Yes (but not now) |
systemctl disable <svc> | Do not start at boot | No |
systemctl enable --now <svc> | Enable and start | Yes |
Status Inspection
| Command | Reports |
|---|---|
systemctl status <svc> | Active state, PID, recent logs |
systemctl is-active <svc> | active or inactive |
systemctl is-enabled <svc> | enabled or disabled |
journalctl -u <svc> | All journal entries for unit |
journalctl -u <svc> -f | Follow new entries |
journalctl -u <svc> -n 50 -f | Last 50 lines + follow |
Custom Unit File Sections
| Section | Purpose | Key Directives |
|---|---|---|
[Unit] | Metadata, dependencies | Description, After |
[Service] | Execution | ExecStart, Restart, User |
[Install] | Boot target for enable | WantedBy=multi-user.target |
Exam Traps
| Trap | Symptom | Fix |
|---|---|---|
| Start without enable | Service dead after reboot | enable --now |
| Enable without start | Service not running now | enable --now |
No daemon-reload | Unit not found after creation | systemctl daemon-reload |
Missing [Install] | enable fails | Add WantedBy |
Editing /usr/lib | Changes lost on package update | Use systemctl edit |
Best Practices
โ Do This:
# Enable and start in one command. // โ
sudo systemctl enable --now nginx
# Reload after creating or editing a unit file. // โ
sudo systemctl daemon-reload
# Use systemctl edit for overrides. // โ
sudo systemctl edit my_app
# Read the journal when a service fails. // โ
journalctl -u my_app -n 100
# Verify both active and enabled states. // โ
systemctl is-active my_app && systemctl is-enabled my_app
โ Don’t Do This:
# Start without enabling for a "start at boot" task. // โ
sudo systemctl start nginx # Dead after reboot.
# Skip daemon-reload after creating a unit. // โ
sudo systemctl start my_app # "Unit not found."
# Edit files in /usr/lib/systemd/system directly. // โ
# Changes overwritten by package updates. Use systemctl edit.
# Assume reload works for every service. // โ
# Some services do not support reload; use restart.
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Service not running after reboot | Started but not enabled | enable --now |
| “Unit not found” after creating file | daemon-reload not run | Run it before start |
| Cannot enable custom service | Missing [Install] section | Add WantedBy=multi-user.target |
| Status shows failed but no error | Logs are in journal, not status | journalctl -u <svc> |
| Configuration change ignored | Service not restarted or reloaded | restart or reload |
Real-World Examples
1. Enable and Start Nginx
sudo systemctl enable --now nginx
2. Check Both States
systemctl is-active nginx && systemctl is-enabled nginx
3. Create Custom Service
sudo tee /etc/systemd/system/app.service <<'EOF'
[Unit]
Description=App
[Service]
ExecStart=/usr/bin/app
[Install]
WantedBy=multi-user.target
EOF
4. Reload After Unit Change
sudo systemctl daemon-reload
5. Follow Service Logs
journalctl -u app -f
6. Last 50 Log Lines
journalctl -u app -n 50
7. Safe Override
sudo systemctl edit app
8. List Failed Units
systemctl --failed
9. Mask a Service
sudo systemctl mask nginx
10. Conditional Restart
sudo systemctl condrestart app # Only if running.
Visual
Enable vs Start
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ENABLE vs START โ
โ โ
โ systemctl start nginx โ
โ โ Runs now โ
โ โ Creates no symlinks โ
โ โ Reboot: NOT running โ
โ โ
โ systemctl enable nginx โ
โ โ Creates symlink in target.wants/ โ
โ โ Does NOT run now โ
โ โ Reboot: running โ
โ โ
โ systemctl enable --now nginx โ
โ โ Creates symlinks โ
โ โ Starts now โ
โ โ Reboot: running โ
โ โ
โ The exam grader reboots. โ
โ Enable is not optional. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Service Unit File Structure
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ my_app.service โ
โ โ
โ [Unit] โ
โ Description=My Application โ
โ After=network.target โ
โ โ โ
โ โ metadata, dependencies โ
โ โผ โ
โ [Service] โ
โ ExecStart=/usr/bin/python3 /opt/app.py โ
โ Restart=always โ
โ User=appuser โ
โ โ โ
โ โ execution model โ
โ โผ โ
โ [Install] โ
โ WantedBy=multi-user.target โ
โ โ โ
โ โ enable target โ
โ โผ โ
โ systemctl enable creates symlink here. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Troubleshooting Flow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SERVICE FAILS TO START โ
โ โ
โ systemctl status my_app โ
โ โ โ
โ โโโ "Unit not found" โ
โ โ โ daemon-reload not run โ
โ โ โ
โ โโโ "Failed with result 'exit-code'" โ
โ โ โ journalctl -u my_app โ
โ โ โ check ExecStart path โ
โ โ โ
โ โโโ "inactive (dead)" โ
โ โ systemctl start my_app โ
โ โ check journal for error โ
โ โ
โ Always read the journal, not just status. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Exam Checklist
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SERVICE TASK VERIFICATION โ
โ โ
โ Task: "Start nginx and ensure it โ
โ starts on boot." โ
โ โ
โ 1. sudo systemctl enable --now nginx โ
โ โ
โ 2. Verify active: โ
โ systemctl is-active nginx โ active โ
โ โ
โ 3. Verify enabled: โ
โ systemctl is-enabled nginx โ enabled โ
โ โ
โ 4. If custom unit: โ
โ sudo systemctl daemon-reload โ
โ โ
โ 5. If failure: โ
โ journalctl -u nginx -n 50 โ
โ โ
โ Both checks must pass. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Start | Runs service now, no boot persistence |
| Enable | Boot persistence, no current start |
enable --now | Both in one command |
| Status | systemctl status, is-active, is-enabled |
| Logs | journalctl -u <svc>, -f follow, -n limit |
| Custom unit location | /etc/systemd/system/<name>.service |
| Required sections | [Unit], [Service], [Install] |
daemon-reload | Required after unit creation or edit |
[Install] target | WantedBy=multi-user.target |
| Mask | Prevents all starts, stronger than disable |
Key takeaways:
startruns now;enablepersists at boot. The exam reboots the machine. A service that was started but not enabled fails the task.systemctl enable --now <service>satisfies both requirements in one command .daemon-reloadis mandatory after creating or editing a unit file. systemd caches unit contents. Without the reload,systemctl startuses the old configuration or reports “unit not found” .- The
[Install]section is what makesenablework.WantedBy=multi-user.targettells systemd which target should pull in the service. Without it, the service can be started manually but cannot be enabled . journalctl -u <service>is the diagnostic tool. Status shows a summary; the full log shows the error.-ffollows,-nlimits .- Use
systemctl editfor overrides, not direct edits to/usr/lib. Drop-in files in/etc/systemd/system/<unit>.d/survive package updates . is-activeandis-enabledare the verification commands. Both must return the expected state after a service task. Checking only one is incomplete.
Remember: systemd service management on the LFCS is a test of operational completeness, not command memorization. The commands are simple: start, stop, enable, disable, status, journalctl. The trap is the gap between “works now” and “works after reboot.” The exam grader reboots. enable --now closes the gap. Custom units add a second trap: the daemon-reload that refreshes the cache and the [Install] section that makes enable possible. Verify both statesโactive and enabledโbefore considering a service task complete.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!