Save products you love by clicking the heart icon.
Compare LPIC-1 exam 101-500 and 102-500: topic breakdown, difficulty, overlap, and whether you should take them together or separately.
Master LPIC-1 101-500: hardware configuration, boot process, disk partitioning, package management, and system maintenance with command examples.
The LPIC-1 102-500 exam is the second of two exams required for the LPIC-1 certification. It covers shell scripting and data management, user interfaces and desktops, administrative tasks, essential networking, and system security.
This guide provides an objective-by-objective breakdown with commands, configuration examples, and exam-relevant details.
Shell configuration files:
| File | Scope | When Read |
|---|---|---|
/etc/profile | System-wide | Login shell |
~/.profile | User | Login shell |
~/.bash_profile | User (bash) | Login shell |
~/.bashrc | User (bash) | Interactive non-login |
/etc/bash.bashrc | System-wide | Interactive non-login |
~/.bash_logout | User | Logout |
Login vs non-login shells:
su -, ssh, terminal login. Reads /etc/profile then ~/.profile or ~/.bash_profile.bash, xterm. Reads ~/.bashrc only.Interactive vs non-interactive shells:
echo $0 # Shows bash or -bash (login)
shopt login_shell # Shows "login_shell" on/off
# Export variables
export PATH=$PATH:/opt/bin
export EDITOR=vim
export PS1='\u@\h:\w\$ ' # Prompt format
export PS2='> ' # Continuation prompt
# Key environment variables
echo $HOME
echo $USER
echo $SHELL
echo $PWD
echo $OLDPWD
echo $TERM
# Set alias
alias ll='ls -l'
alias la='ls -la'
alias rm='rm -i'
# Functions
myfunc() { echo "Hello $1"; }
export -f myfunc # Export function to subshells
Prompt customization (PS1):
| Placeholder | Meaning |
|---|---|
\u | Username |
\h | Hostname (short) |
\H | Full hostname |
\w | Current directory (full) |
\W | Current directory (basename) |
\d | Date (Day Mon Date) |
\t | Time (HH:MM:SS) |
\@ | Time (12h AM/PM) |
\$ | # for root, $ for user |
\! | History number |
\# | Command number |
#!/bin/bash
# Shebang — determines interpreter
# Variables
NAME="World"
echo "Hello $NAME"
echo "Hello ${NAME}!"
read -p "Enter name: " input_name
# Positional parameters
echo "Script: $0"
echo "Arg 1: $1"
echo "Arg 2: $2"
echo "Arg count: $#"
echo "All args: $@"
echo "All args: $*"
shift # Shift positional params left
# Exit status
ls /nonexistent
echo $? # Previous command exit code (0=success)
exit 0 # Exit script with status
exit 1 # Exit with error
# Conditionals
if [ -f "$file" ]; then
echo "File exists"
elif [ -d "$dir" ]; then
echo "Directory exists"
else
echo "Neither"
fi
# Test operators
# -f file File exists and is regular
# -d dir Directory exists
# -e file File exists (any type)
# -r file Readable
# -w file Writable
# -x file Executable
# -s file Non-empty
# -z string String is empty
# -n string String is non-empty
# file1 -nt file2 Newer than
# file1 -ot file2 Older than
# String comparison
[ "$a" = "$b" ] # Equal (POSIX)
[ "$a" == "$b" ] # Equal (bash)
[ "$a" != "$b" ] # Not equal
[[ "$a" < "$b" ]] # Less than (lexicographic, bash)
# Integer comparison
[ "$a" -eq "$b" ] # Equal
[ "$a" -ne "$b" ] # Not equal
[ "$a" -gt "$b" ] # Greater than
[ "$a" -ge "$b" ] # Greater or equal
[ "$a" -lt "$b" ] # Less than
[ "$a" -le "$b" ] # Less or equal
# Arithmetic
$(( a + b ))
$(( a * b ))
let "a = a + 1"
(( a++ ))
# Loops
for i in {1..5}; do
echo $i
done
for file in /etc/*.conf; do
echo $file
done
while [ "$count" -lt 10 ]; do
echo $count
(( count++ ))
done
until [ "$count" -eq 0 ]; do
echo $count
(( count-- ))
done
# Case statement
case "$1" in
start) echo "Starting...";;
stop) echo "Stopping...";;
restart) echo "Restarting...";;
*) echo "Usage: $0 {start|stop|restart}"; exit 1;;
esac
# Functions
function myfunction {
local local_var="I'm local"
echo "$1 is first arg to function"
}
myfunction "argument"
# Sourcing vs executing
. script.sh # Source (same shell)
source script.sh # Source (bash)
./script.sh # Execute (subshell)
bash script.sh # Execute (subshell)
# Open SQLite
sqlite3 database.db
# SQLite commands
sqlite> .tables # List tables
sqlite> .schema table # Show CREATE statement
sqlite> .headers on # Show column headers
sqlite> .mode column # Columnar output
sqlite> .quit # Exit
# Basic SQL
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE,
created DATE DEFAULT CURRENT_DATE
);
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
SELECT * FROM users;
SELECT name FROM users WHERE email LIKE '%example.com';
UPDATE users SET name='Bob' WHERE id=1;
DELETE FROM users WHERE id=1;
DROP TABLE users;
# Import CSV
.mode csv
.import data.csv table_name
# Export
.output out.csv
SELECT * FROM users;
.output stdout
# Backup
.dump > backup.sql
.restore backup.sql
# From command line
sqlite3 db.db "SELECT * FROM users;"
sqlite3 db.db ".dump" > backup.sql
# X11 configuration file
cat /etc/X11/xorg.conf
# Modern systems auto-detect; manual config rarely needed
# X server display numbers
# :0 — first local display
# :1 — second local display
# Display manager (DM) — graphical login
# GDM (GNOME), LightDM, SDDM (KDE), XDM
# Window managers
# Stacking: Openbox, Fluxbox, twm
# Tiling: i3, dwm, Awesome, bspwm
# Desktop environments
# GNOME (gtk-based), KDE Plasma (qt-based), Xfce (lightweight)
# Start X manually
startx
xinit /usr/bin/startxfce4
# Remote X forwarding (SSH)
ssh -X user@host # Trusted forwarding
ssh -Y user@host # Untrusted forwarding
# DISPLAY variable
export DISPLAY=:0
export DISPLAY=192.168.1.10:0 # Remote display
# Wayland (X11 successor)
# Most modern Linux distributions default to Wayland
echo $XDG_SESSION_TYPE # x11 or wayland
# Desktop environments use display managers
# GNOME Keyring — stores credentials
# KDE Wallet — similar functionality
# Accessibility features
# Orca — screen reader
# Compiz — compositing window manager (legacy)
# Mutter — GNOME compositor
# KWin — KDE compositor
# Accessibility technologies
# Screen readers: Orca, Speakup
# Screen magnifiers: KMagnifier, GNOME Magnifier
# On-screen keyboard: onboard, florence
# Sticky keys, slow keys, bounce keys — assistive technology
# Accessibility settings
gsettings set org.gnome.desktop.a11y.applications screen-reader-enabled true
# User management
useradd -m -s /bin/bash -G sudo alice
useradd -u 1500 -g users -G wheel -c "Alice Smith" -d /home/alice -s /bin/bash alice
usermod -aG docker alice # Append to group
usermod -L alice # Lock account
usermod -U alice # Unlock
userdel alice # Remove user
userdel -r alice # Remove user and home
# Password management
passwd alice
passwd -l alice # Lock password
passwd -u alice # Unlock
passwd -S alice # Status
passwd -d alice # Delete password (no login)
# Group management
groupadd developers
groupdel developers
groupmod -n devs developers # Rename group
gpasswd -a alice developers # Add user to group
gpasswd -d alice developers # Remove user from group
# User info commands
id alice
id -u alice
id -g alice
id -G alice # All group IDs
whoami
groups alice
finger alice
chfn alice # Change full name/office/phone
chsh -s /bin/zsh alice # Change shell
Key account files:
| File | Purpose |
|---|---|
/etc/passwd | User accounts (7 colon-delimited fields: user:pass:UID:GID:comment:home:shell) |
/etc/shadow | Encrypted passwords and expiry info |
/etc/group | Group definitions |
/etc/gshadow | Group passwords (rarely used) |
/etc/default/useradd | Default values for useradd |
/etc/login.defs | System-wide login policy (UID ranges, password aging defaults) |
/etc/skel/ | Skeleton directory for new users |
Password aging:
chage -l alice # List aging info
chage -M 90 alice # Max days (90)
chage -m 7 alice # Min days between changes
chage -W 14 alice # Warning days
chage -E 2027-01-01 alice # Expiration date
chage -d 0 alice # Force password change on next login
Cron:
# Format: minute hour day month weekday command
# Example: 30 2 * * * /usr/bin/backup.sh (daily 2:30 AM)
# Special time strings
@reboot # Run at boot
@daily # Run once a day (0 0 * * *)
@weekly # Run once a week (0 0 * * 0)
@monthly # Run once a month (0 0 1 * *)
@yearly # Run once a year (0 0 1 1 *)
# Manage crontabs
crontab -e # Edit crontab for current user
crontab -l # List crontab
crontab -r # Remove crontab
crontab -u alice -e # Edit another user's crontab (root)
# System-wide cron
ls /etc/cron.hourly/
ls /etc/cron.daily/
ls /etc/cron.weekly/
ls /etc/cron.monthly/
cat /etc/crontab # System crontab (includes user field)
ls /etc/cron.d/ # Package-specific cron jobs
# Cron allow/deny
cat /etc/cron.allow # Users allowed to use cron
cat /etc/cron.deny # Users denied from using cron
Systemd timers (cron alternative):
# Create timer unit
cat /etc/systemd/system/backup.timer
# [Unit]
# Description=Daily backup
# [Timer]
# OnCalendar=daily
# Persistent=true
# [Install]
# WantedBy=timers.target
# Create service unit
cat /etc/systemd/system/backup.service
# [Unit]
# Description=Run backup
# [Service]
# ExecStart=/usr/bin/backup.sh
# Manage timers
systemctl enable --now backup.timer
systemctl list-timers
At (one-time scheduled tasks):
at now + 5 minutes
at> /usr/bin/backup.sh
at> Ctrl+D
at now + 2 hours
at 14:00 today
at 3:00 AM tomorrow
at 3:00 PM July 15
atq # List pending jobs
atrm 5 # Remove job 5
batch # Run when system load permits
# at allow/deny
cat /etc/at.allow
cat /etc/at.deny
# Locale settings
locale # Show current locale
locale -a # List all available locales
localectl # System locale configuration
localectl list-locales
# Set locale
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LC_MESSAGES=de_DE.UTF-8 # Message language
# Environment variables
# LANG, LC_ALL, LC_MESSAGES, LC_TIME, LC_NUMERIC, LC_COLLATE, LC_MONETARY, LC_CTYPE
# Timezone
timedatectl # Show and set timezone
timedatectl list-timezones
timedatectl set-timezone Europe/Berlin
# Time-related files
cat /etc/timezone
ls -l /etc/localtime # Symlink to /usr/share/zoneinfo/...
# Character encoding
iconv -f UTF-8 -t ISO-8859-1 input.txt > output.txt
file -i file.txt # Show character encoding
# Keyboard layout
localectl list-keymaps
localectl set-keymap us
loadkeys de # Load German layout immediately
# Hardware clock (RTC)
hwclock # Show hardware clock
hwclock --show
hwclock --set --date="2026-07-13 12:00:00"
hwclock --systohc # Write system time to hardware clock
hwclock --hctosys # Read hardware clock to system
# NTP with chrony (modern standard)
systemctl status chronyd
chronyc sources # Show NTP sources
chronyc tracking # Show system clock offset
chronyc -n sources # Numeric output
chronyc activity # Active sources
# NTP with ntpd (traditional)
ntpq -p # Show NTP peers
ntpdate pool.ntp.org # One-time sync (deprecated)
# systemd-timesyncd
timedatectl set-ntp true
cat /etc/systemd/timesyncd.conf
# rsyslog (traditional)
cat /etc/rsyslog.conf
cat /etc/rsyslog.d/*.conf
# Log format: facility.priority action
# auth.info /var/log/auth.log
# *.info;mail.none;authpriv.none /var/log/messages
# Key log files
/var/log/syslog # Generic system log
/var/log/messages # System messages (RHEL)
/var/log/auth.log # Authentication (Debian)
/var/log/secure # Authentication (RHEL)
/var/log/kern.log # Kernel
/var/log/dmesg # Kernel ring buffer
/var/log/boot.log # Boot messages
/var/log/mail.log # Mail server
/var/log/apache2/ # Apache web server
# Log rotation (logrotate)
cat /etc/logrotate.conf
cat /etc/logrotate.d/*
# systemd journal
journalctl
journalctl -xe # Recent with explanation
journalctl -u nginx.service # Specific unit
journalctl -p err # Error priority and above
journalctl -f # Follow (like tail -f)
journalctl --since "1 hour ago"
journalctl --until "2026-07-13 12:00"
journalctl -k # Kernel messages
journalctl --list-boots # List boot sessions
journalctl --disk-usage # Journal size
# Preserve journal across reboots
mkdir -p /var/log/journal
systemd-tmpfiles --create --prefix /var/log/journal
# Common MTAs: Postfix, Sendmail, Exim
# Send mail from command line
mail -s "Subject" user@example.com
mail -s "Subject" alice < /tmp/report.txt
echo "Body text" | mail -s "Subject" alice
# Check mail queue
mailq
postqueue -p # Postfix mail queue
# /etc/aliases - local aliases
# root: alice
# postmaster: root
# Run newaliases after editing
newaliases
# Mail spool
ls /var/mail/
ls /var/spool/mail/
# CUPS (Common Unix Printing System)
systemctl status cups
lpinfo -v # Available printers/drivers
lpinfo -m # Available models/drivers
# Add printer
lpadmin -p printername -E -v usb://device -m everywhere
# Print files
lp -d printername file.pdf
lp -n 2 file.pdf # 2 copies
lp -o media=A4 file.pdf
lp -o sides=two-sided-long-edge file.pdf
lpr -P printername file.pdf
# Check queues
lpq -P printername
lpstat -t
lpstat -p printername
lpstat -d # Default printer
# Remove jobs
lprm jobid
lprm -P printername - # Remove all jobs
# Set default printer
lpoptions -d printername
lpadmin -d printername
# CUPS configuration
cat /etc/cups/cupsd.conf
# IPv4 addresses
# Classes: A (1-126), B (128-191), C (192-223), D (multicast), E (reserved)
# Private ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
# Loopback: 127.0.0.0/8
# IPv6
# Format: 2001:db8::1
# Loopback: ::1
# Link-local: fe80::/10
# Subnet masks
# /24 = 255.255.255.0 = 254 hosts
# /16 = 255.255.0.0 = 65534 hosts
# /8 = 255.0.0.0 = 16777214 hosts
# Key protocols
# TCP — connection-oriented, reliable
# UDP — connectionless, fast
# ICMP — error reporting (ping)
# FTP — file transfer (ports 20, 21)
# SSH — secure shell (port 22)
# Telnet — unencrypted remote (port 23)
# SMTP — email sending (port 25)
# DNS — name resolution (port 53)
# HTTP — web (port 80)
# HTTPS — secure web (port 443)
# POP3 — email receiving (port 110)
# IMAP — email receiving (port 143)
# Network configuration files (Debian/Ubuntu)
cat /etc/network/interfaces
# auto eth0
# iface eth0 inet static
# address 192.168.1.100
# netmask 255.255.255.0
# gateway 192.168.1.1
# dns-nameservers 8.8.8.8
# Network configuration (RHEL/Fedora)
cat /etc/sysconfig/network-scripts/ifcfg-eth0
# DEVICE=eth0
# BOOTPROTO=static
# IPADDR=192.168.1.100
# NETMASK=255.255.255.0
# GATEWAY=192.168.1.1
# DNS1=8.8.8.8
# ONBOOT=yes
# Netplan (Ubuntu modern)
cat /etc/netplan/*.yaml
# NetworkManager
nmcli dev status
nmcli connection show
nmcli connection up eth0
nmtui # Text UI
# ip commands (modern)
ip addr show # Show interfaces
ip route show # Show routing table
ip link set eth0 up
ip link set eth0 down
ip addr add 192.168.1.100/24 dev eth0
ip route add default via 192.168.1.1
# ifconfig commands (legacy)
ifconfig
ifconfig eth0 up
ifconfig eth0 192.168.1.100 netmask 255.255.255.0
# DNS
cat /etc/resolv.conf # Name servers
cat /etc/hosts # Static host → IP mappings
cat /etc/nsswitch.conf # Name resolution order
# Hostname
hostname
hostname -f # Fully qualified domain name
hostnamectl set-hostname server.example.com
# Connectivity
ping 8.8.8.8
ping -c 4 192.168.1.1 # Stop after 4 packets
ping -6 ipv6.google.com
# Path
traceroute 8.8.8.8
traceroute -n 8.8.8.8 # Numeric (no DNS)
mtr 8.8.8.8 # Combined ping + traceroute
# DNS resolution
host example.com
nslookup example.com
dig example.com
dig -x 8.8.8.8 # Reverse lookup
getent hosts example.com # Using system name resolution
# Network connections
ss -tulpn # Listening ports (modern)
netstat -tulpn # Listening ports (legacy)
ss -ta # All TCP connections
ss -ua # All UDP connections
# Bandwidth
iperf3 -c server.example.com
speedtest-cli # Internet speed test
# ARP
arp -a # ARP table
ip neighbor show # Modern ARP view
# Packet capture
tcpdump -i eth0
tcpdump -i eth0 port 80
tcpdump -i eth0 host 192.168.1.1
tcpdump -w capture.pcap # Write to file
tcpdump -r capture.pcap # Read from file
# /etc/hosts
# 127.0.0.1 localhost
# 192.168.1.100 server.example.com server
# /etc/nsswitch.conf
# hosts: files dns myhostname
# Order: check /etc/hosts first, then DNS
# /etc/resolv.conf
# nameserver 8.8.8.8
# nameserver 8.8.4.4
# search example.com # Append domain for unqualified names
# options timeout:2 attempts:3 rotate
# systemd-resolved
resolvectl status
resolvectl query example.com
cat /etc/systemd/resolved.conf
Already covered in 109.2. Additional tools:
# Wireless
iwconfig
iwlist wlan0 scan
nmcli dev wifi list
nmcli dev wifi connect SSID password PASSWORD
# Bluetooth
bluetoothctl
hciconfig
# User authentication files
cat /etc/passwd # User accounts
cat /etc/shadow # Encrypted passwords
cat /etc/group # Groups
# ! in /etc/shadow password field = account locked
# * = no login possible
# $y$ = yescrypt hash, $6$ = SHA-512, $5$ = SHA-256
# Check for empty passwords
awk -F: '($2 == "")' /etc/shadow
# Limits configuration
cat /etc/security/limits.conf
# alice hard nproc 100
# @users soft nofile 1024
cat /etc/security/limits.d/*.conf
# su and sudo
su alice # Switch user (needs password)
su - alice # Login shell
sudo -l # List allowed commands
sudo -u alice command # Run as user
visudo # Edit /etc/sudoers safely
# /etc/sudoers format
# alice ALL=(ALL:ALL) ALL
# %wheel ALL=(ALL:ALL) ALL
# alice ALL=(root) /usr/bin/systemctl
# Kernel parameters
sysctl -a
sysctl net.ipv4.ip_forward
sysctl -w net.ipv4.ip_forward=1
cat /etc/sysctl.conf
cat /etc/sysctl.d/*.conf
# Shadow password suite
pwck # Verify /etc/passwd integrity
grpck # Verify /etc/group integrity
# File ownership and permissions
find / -nouser -o -nogroup # Files with no owner/group
find / -perm -4000 # SUID files
find / -perm -2000 # SGID files
find / -perm -1000 # Sticky bit
# SSH security
cat /etc/ssh/sshd_config
# PermitRootLogin no
# PasswordAuthentication no
# PubkeyAuthentication yes
# Port 2222
# Firewall (iptables/nftables)
iptables -L -n -v # List rules
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j DROP # Default deny
# Firewall (firewalld)
firewall-cmd --list-all
firewall-cmd --add-service=http --permanent
firewall-cmd --reload
# UFW (Uncomplicated Firewall)
ufw enable
ufw allow ssh
ufw allow 80/tcp
ufw status
# GPG
gpg --gen-key # Generate key pair
gpg --list-keys
gpg -e -r alice file.txt # Encrypt for alice
gpg -d file.txt.gpg # Decrypt
gpg --sign file.txt # Sign
gpg --verify file.txt.asc # Verify signature
gpg --export -a alice > alice.asc # Export public key
gpg --import alice.asc # Import public key
# SSH key-based auth
ssh-keygen -t ed25519 -C "alice@example.com"
ssh-keygen -t rsa -b 4096
ssh-copy-id alice@server
cat ~/.ssh/id_ed25519.pub # Public key
cat ~/.ssh/id_ed25519 # Private key (keep secret!)
# SSH agent
eval $(ssh-agent)
ssh-add ~/.ssh/id_ed25519
ssh-add -l # List loaded keys
ssh-add -L # List public keys
# /dev/null and shred
shred -f file.txt # Overwrite 3 times
shred -n 10 file.txt # Overwrite 10 times
shred -z file.txt # Add final zero overwrite
ip, ss, and dig are heavily testedman -k keyword is the fastest way to find the right command during the exam (if allowed)Ready to put this knowledge to the test? Our LPI practice portal includes 200+ realistic questions covering LPIC-1, LPIC-2, LPIC-3, and DevOps Tools Engineer certifications. Study mode, timed exams, domain breakdowns, and weak-area analysis included.