LPIC-1 102-500 common mistakes
LPIC-1 102-500 · Understand the traps and how to avoid them.
Writing shell scripts that use bash-only syntax ([[ ]], arrays, $((...)) with let-style tricks, process substitution) while the shebang says /bin/sh, then being surprised when the script fails on a dash-based system.
Candidates learn scripting interactively in bash and assume /bin/sh is bash; on Debian-derived systems /bin/sh is dash, so constructs like [[ ]] and function-local arrays break. They also forget that the shebang line, not the login shell, determines the interpreter.
What to do instead
Decide the interpreter explicitly: use #!/bin/bash when you rely on bash features, or rewrite POSIX-only with [ ] and case. Test scripts with sh script.sh and bash script.sh, and verify the shebang is the first line with no leading whitespace. Know that bash --posix and dash differ on [[, ==, and source vs .
Misusing quoting and redirection in scripts and on the command line: unquoted variables splitting on whitespace, 2>&1 placed before the > file, and confusing > with >> when appending logs.
Word splitting and globbing happen after parameter expansion, so unquoted $var breaks on filenames with spaces. Redirection order is evaluated left to right, so cmd 2>&1 > file sends stderr to the terminal, not the file. Candidates memorize 2>&1 without understanding ordering.
What to do instead
Quote expansions ("$var", "${arr[@]}"), use "$@" not $@, and write cmd > file 2>&1 (or &> file in bash) so stderr follows stdout. Use set -u to catch unset variables and shellcheck-style review for unquoted expansions. Practice reading redirection left to right and predict where each fd points.
Treating cron and systemd timers as interchangeable and getting the schedule syntax or environment wrong: using @reboot in a system crontab, assuming cron inherits the login PATH, or editing /etc/crontab with crontab -e.
cron runs with a minimal environment and a different PATH than an interactive shell, so scripts that call commands by bare name fail. System crontabs (/etc/crontab, /etc/cron.d/*) have a user field that user crontabs lack, and @reboot is per-user only. Candidates also confuse cron.daily with systemd timers on modern distros.
What to do instead
In cron jobs use absolute paths or set PATH at the top of the crontab, redirect output to a log, and remember the six-field system format vs five-field user format. Test with run-parts --test /etc/cron.daily. For systemd, use OnCalendar= with systemd-analyze calendar to validate, and systemctl list-timers to confirm the next run.
Confusing syslog facilities and priorities, and not knowing where logs land on a systemd-journald host: expecting /var/log/messages to always exist, or misreading a severity such as warning vs err.
Facilities (auth, authpriv, kern, daemon, local0-7) and severities (emerg through debug) are tested as discrete facts, and rsyslog vs journald vs both varies by distribution. Candidates assume one log file layout across all systems.
What to do instead
Memorize the facility list and the severity order emerg(0) to debug(7), and note that a rule like authpriv.* /var/log/secure captures all severities. On journald systems use journalctl -u unit, journalctl -p err, journalctl --since, and journalctl -b. Check /etc/rsyslog.conf and /etc/rsyslog.d/ to see which files a host actually writes.
Miscalculating subnet, broadcast, and host ranges from a CIDR prefix, or misapplying the private address ranges and default route concepts.
Candidates memorize /24 and guess at /25, /26, and /27, or forget that the network and broadcast addresses are unusable. They also mix up which RFC1918 block is which (10/8, 172.16/12, 192.168/16) and treat the default gateway as optional.
What to do instead
Practice the block-size method: for /26 the block is 64, so subnets start at .0, .64, .128, .192; usable hosts are block minus 2. Use ipcalc or ip -4 addr and ip route to verify. Memorize the RFC1918 ranges and the fact that the default route (0.0.0.0/0) points to the gateway, and that a host needs both an address and a route to reach off-link destinations.
Not knowing which file configures which resolver or interface setting: editing /etc/resolv.conf directly on a NetworkManager host, or confusing /etc/hosts, /etc/nsswitch.conf, and /etc/hostname.
Modern distros regenerate /etc/resolv.conf via NetworkManager, systemd-resolved, or dhclient, so manual edits are overwritten. Candidates also assume DNS is the only name source and forget nsswitch.conf controls the order (files dns).
What to do instead
Learn the chain: nsswitch.conf sets lookup order, /etc/hosts provides static entries, and resolv.conf (or resolved) provides nameservers. On NetworkManager set DNS in the connection profile (nmcli con mod ... ipv4.dns) rather than editing resolv.conf; on systemd-resolved use resolvectl. Verify with getent hosts and dig/host against a specific server.
Managing users and groups by hand-editing /etc/passwd or /etc/shadow, or forgetting supplementary groups and password-lock state when auditing accounts.
Direct edits skip shadow hashing and can break field counts; candidates also forget that usermod -G replaces supplementary groups unless -a is used, and misread the shadow field (!! or * meaning locked, not empty).
What to do instead
Use useradd/usermod/groupadd and passwd -l/-u for locking. Add supplementary groups with usermod -aG group user. Read /etc/passwd fields (name:x:uid:gid:gecos:home:shell) and /etc/shadow (name:hash:lastchg:min:max:warn:inactive:expire). Check with id, groups, and getent passwd user. Use chage -l to inspect aging.
Getting file permissions and special bits wrong: assuming chmod 777 is a fix, forgetting umask subtracts from 666/777, or not knowing what setuid, setgid, and sticky mean.
Candidates compute permissions from memory instead of the umask formula, and confuse setgid on a directory (new files inherit the group) with setgid on an executable (runs with file group). The sticky bit on /tmp is often misidentified.
What to do instead
Compute defaults as base minus umask: umask 022 gives 644 files and 755 dirs. Memorize the octal bits 4000 setuid, 2000 setgid, 1000 sticky, and see them as s/S and t/T in ls -l. Practice chmod u+s, g+s, o+t and verify with stat. Know that setgid on a directory makes new files inherit the directory's group, not the user's primary group.
Misconfiguring SSH access control: disabling password auth before installing keys, wrong permissions on ~/.ssh, or not understanding sshd_config directives such as PermitRootLogin, AllowUsers, and Port.
sshd refuses keys if ~/.ssh is group/world-writable or if authorized_keys has loose permissions, and candidates lock themselves out by removing password auth first. They also assume changes apply without reloading sshd.
What to do instead
Set chmod 700 ~/.ssh and 600 ~/.ssh/authorized_keys with correct ownership. Test key login in a second session before setting PasswordAuthentication no. Validate with sshd -t, reload with systemctl reload sshd, and use AllowUsers/DenyUsers and PermitRootLogin prohibit-password deliberately. Remember client config lives in ~/.ssh/config and /etc/ssh/ssh_config.
Treating X11 and Wayland display concepts as trivia: not knowing DISPLAY, xauth, or how to start a session, and ignoring the difference between a display manager and a desktop environment.
Candidates lump together X server, display manager (gdm, lightdm, sddm), and desktop environment (GNOME, KDE, Xfce), and cannot explain why an SSH-forwarded GUI needs DISPLAY and X authority. Wayland changes where these settings live.
What to do instead
Separate the layers: X server or Wayland compositor renders, the display manager handles login, and the desktop environment provides the session. Know DISPLAY=:0, xauth list, and ssh -X vs -Y. Check session type with loginctl show-session and echo $XDG_SESSION_TYPE. Read /etc/X11/xorg.conf.d/ and the display-manager unit to locate configuration.