🐧

Linux System Administration Intermediate

Run Linux with confidence: the shell, filesystem, permissions, processes, packages, services and networking.

16 lessons 48 quiz questions
Lessons & quizzes Certificate

📚 Lessons & quizzes

Each lesson ends with its own short quiz. Answer them as you go — score 90% across all lessons to earn your certificate.

1 The shell and the terminal

The shell is a program that reads the commands you type and asks the kernel to run them. The most common Linux shell is Bash (the Bourne-Again SHell). The terminal (or terminal emulator) is just the window that hosts the shell — it shows the prompt, your keystrokes and the program output.

A command line is split into words separated by spaces: the first word is the command, the rest are its arguments and options. Options usually start with a dash, like -l, or two dashes for long names, like --help. The prompt often ends in $ for a normal user and # for the root (superuser) account, which is a quick way to tell whether you have administrative power.

# Who am I, and what shell am I running?
whoami
echo "My shell is: $SHELL"

# Ask any command for built-in help
ls --help | head -n 5

2 The filesystem hierarchy

Linux organises everything under a single root directory, written /. There are no drive letters; every disk is attached (mounted) somewhere inside that one tree. The Filesystem Hierarchy Standard gives each top-level directory a job.

Key directories: /etc holds system-wide configuration files; /var holds variable data such as logs (/var/log) and mail; /home holds each user’s personal directory (for example /home/aleksi); /bin and /usr/bin hold executable programs; /tmp is for temporary files; and /root is the superuser’s home. Knowing where things live saves you searching the whole disk.

# List the top-level directories of the system
ls -l /

# Configuration lives in /etc; logs in /var/log
ls /etc | head
ls /var/log | head

3 Navigating and managing files

You move around with cd (change directory) and find out where you are with pwd (print working directory). The shortcut cd with no argument, or cd ~, returns you to your home directory, and cd .. goes up one level.

ls lists directory contents; ls -l gives a long listing with permissions, owner and size, and ls -a shows hidden files (those whose name starts with a dot). To manage files: mkdir makes directories, cp copies, mv moves or renames, and rm removes. Be careful: rm -r deletes a directory and everything inside it, and there is no recycle bin.

cd ~                 # go to your home directory
pwd                  # show where you are
mkdir projects       # make a new directory
cp notes.txt projects/    # copy a file into it
mv old.txt new.txt        # rename a file
rm -r projects            # remove a directory and its contents

4 Viewing files and redirection

To read files: cat dumps the whole file to the screen, while less opens a scrollable pager (press q to quit). For editing in the terminal, nano is beginner-friendly and vim is powerful but modal.

Redirection sends a program’s output somewhere other than the screen. command > file writes output to a file, replacing its contents; command >> file appends instead. A pipe, written |, feeds one command’s output straight into the next command’s input — for example ls | less. Combining these is the heart of Linux power: small tools chained together.

echo "first line"  > log.txt   # > overwrites the file
echo "second line" >> log.txt   # >> appends to it
cat log.txt                      # show the whole file

# Pipe: feed ls output into a pager
ls -l /etc | less

5 Users and groups

Linux is multi-user. Each account has a numeric user ID (UID) and belongs to one or more groups. The file /etc/passwd lists accounts (username, UID, home directory, login shell), and /etc/group lists groups. Passwords themselves are stored hashed in /etc/shadow.

Administrators create accounts with useradd (and set a password with passwd), and remove them with userdel. The root user (UID 0) can do anything. Rather than logging in as root, you run a single command with sudo — it temporarily grants administrative rights, prompts for your password, and records the action in a log for accountability.

# Inspect your identity and groups
id
groups

# Create a user and set a password (needs admin rights)
sudo useradd -m alice    # -m creates the home directory
sudo passwd alice

# See an account line in the user database
grep alice /etc/passwd

6 Permissions: rwx, chmod and chown

Every file has three permission sets — for the owner, the group and others — each with three bits: r (read), w (write) and x (execute). In ls -l you read them left to right, e.g. rwxr-xr-x.

chmod changes permissions. In numeric form each set is a digit: r=4, w=2, x=1, summed. So chmod 755 means owner rwx (4+2+1=7) and group/others r-x (4+1=5), i.e. rwxr-xr-x; chmod 644 means rw-r--r--. In symbolic form you write changes like chmod u+x file (add execute for the owner). chown changes the file’s owner, and chown user:group changes both owner and group.

ls -l script.sh           # see current permissions
chmod 755 script.sh       # rwxr-xr-x (owner full, others read+execute)
chmod u+x script.sh       # symbolic: add execute for the owner
chmod 644 notes.txt       # rw-r--r--
sudo chown alice:staff notes.txt   # change owner and group

7 Default permissions: umask

When a program creates a file it asks for a base set of permissions — typically 666 (rw-rw-rw-) for files and 777 for directories. The umask then removes bits from that base, giving you safe defaults. The umask is a mask of bits to subtract.

A common umask is 022. For a new file: 666 minus the masked bits 022 leaves 644 (rw-r--r--). For a new directory: 777 minus 022 leaves 755 (rwxr-xr-x). Set a stricter mask like 077 and new files become 600 — readable and writable only by you. Run umask alone to see the current value.

umask              # show the current mask, e.g. 0022
umask 077          # tighten: new files become rw------- (600)
touch private.txt
ls -l private.txt  # confirm only the owner can read/write

8 Processes and job control

Every running program is a process with a numeric process ID (PID). ps aux lists processes in a snapshot, while top (or htop) shows them live, sorted by CPU or memory use. To stop a process you send it a signal with kill: kill PID asks it politely (TERM), and kill -9 PID forces it (KILL).

You can run a command in the background by ending it with &; then jobs lists your background jobs, fg brings one to the foreground and bg resumes a paused one in the background. nice starts a process with a lower scheduling priority (a higher niceness value means it yields CPU to others), and renice adjusts a running process.

ps aux | grep firefox     # find a process and its PID
sleep 300 &               # run in the background
jobs                      # list background jobs
kill %1                   # stop background job number 1
nice -n 10 ./batch.sh     # run with lower priority

9 Package management

Software is installed from packages pulled from online repositories that your distribution trusts. Debian and Ubuntu use apt with .deb packages; Fedora, RHEL and friends use dnf with .rpm packages. The package manager resolves dependencies automatically, so installing one program also pulls in the libraries it needs.

On Debian/Ubuntu you first refresh the package index with apt update, then apt install NAME to add software, apt remove NAME to delete it, and apt upgrade to update everything. On Fedora the equivalents are dnf install, dnf remove and dnf upgrade. These commands need administrative rights, so you prefix them with sudo.

# Debian / Ubuntu
sudo apt update              # refresh the package index first
sudo apt install nginx
sudo apt remove nginx

# Fedora / RHEL
sudo dnf install nginx
sudo dnf upgrade

10 Services with systemd

Most modern Linux systems manage background services (daemons) with systemd. The control tool is systemctl. Each service is a unit, typically named like nginx.service.

Common actions: systemctl start NAME starts a service now; systemctl stop NAME stops it; systemctl status NAME shows whether it is running and recent log lines; and systemctl restart NAME bounces it. The crucial distinction: systemctl start only affects the current session, while systemctl enable NAME makes the service start automatically at every boot (and disable undoes that). To read logs, systemd provides journalctl, e.g. journalctl -u nginx for one unit’s messages.

sudo systemctl start nginx     # start it now
sudo systemctl enable nginx    # also start it at every boot
systemctl status nginx         # is it running? recent log lines
sudo systemctl restart nginx
journalctl -u nginx --since today

11 Scheduling tasks with cron

cron runs commands automatically on a schedule. Each user has a crontab (cron table) edited with crontab -e and listed with crontab -l. Each line has five time fields followed by the command to run.

The five fields, in order, are: minute (0–59), hour (0–23), day of month (1–31), month (1–12) and day of week (0–6, Sunday=0). An asterisk * means “every”. So 0 2 * * * means “at 02:00 every day”, and */15 * * * * means “every 15 minutes”. For occasional one-off jobs at a future time, the at command is simpler.

crontab -l                # list your scheduled jobs
crontab -e                # edit them

# A crontab line: run a backup at 02:00 every day
0 2 * * * /home/aleksi/backup.sh

# Every 15 minutes, append the date to a log
*/15 * * * * date >> /tmp/heartbeat.log

12 Networking basics

The modern tool for inspecting and configuring network interfaces is ip. ip addr shows interfaces and their IP addresses; ip route shows the routing table, including the default gateway. To see which ports are listening, ss -tuln lists TCP and UDP sockets in numeric form.

For testing reachability, ping HOST sends ICMP echo requests and reports round-trip time. To fetch data over HTTP from the command line, curl URL downloads a page or API response and prints it; add -I to see only the response headers. Together these answer the everyday questions: do I have an address, can I reach the gateway, can I reach the internet, and is my service listening?

ip addr                 # show interfaces and IP addresses
ip route                # show the routing table / default gateway
ss -tuln                # which TCP/UDP ports are listening
ping -c 4 1.1.1.1       # send 4 pings to test reachability
curl -I https://example.com   # fetch only the HTTP headers

13 Disks, mounts and /etc/fstab

To see free space, df -h reports each filesystem’s size and usage in human-readable units; to find what is filling a directory, du -sh DIR sums its total size. A storage device must be mounted — attached to a directory (its mount point) — before you can use it.

You mount manually with mount /dev/sdb1 /mnt/data and detach with umount /mnt/data. To mount filesystems automatically at boot, you list them in /etc/fstab; each line gives the device (often by UUID), the mount point, the filesystem type and options. A mistake there can stop the system from booting cleanly, so edit it carefully and test with mount -a.

df -h                  # free space per filesystem, human-readable
du -sh /var/log        # total size of a directory
sudo mount /dev/sdb1 /mnt/data   # attach a device to a mount point
sudo umount /mnt/data            # detach it
sudo mount -a                    # mount everything listed in /etc/fstab

14 Archives and file transfer

tar bundles many files into one archive. The common combination tar -czf backup.tar.gz dir/ creates (c) a gzip-compressed (z) archive into a file (f); to extract you swap c for x: tar -xzf backup.tar.gz. The gzip tool compresses a single file in place (and gunzip reverses it).

To move files between machines you have two great tools. scp copies over SSH: scp file user@host:/path. rsync is smarter — it transfers only the differences, making repeated syncs fast; rsync -av src/ user@host:/dest/ mirrors a directory, where -a preserves permissions and timestamps and -v is verbose.

tar -czf backup.tar.gz /home/aleksi/projects   # create a compressed archive
tar -xzf backup.tar.gz                          # extract it

scp report.pdf aleksi@server:/tmp/              # copy over SSH
rsync -av ./site/ aleksi@server:/var/www/site/  # sync only the differences

15 Shell scripting basics

A shell script is a text file of commands you can run as a program. The first line, the shebang #!/bin/bash, tells the system which interpreter to use. Make the file executable with chmod +x and run it with ./script.sh.

Variables are assigned with no spaces, like name=value, and used with a dollar sign, like $name. Arguments passed to the script are $1, $2 and so on. An if statement makes decisions, and a for loop repeats over a list. Always quote variables ("$name") so values with spaces behave correctly.

#!/bin/bash
name="$1"                       # first argument
if [ -z "$name" ]; then        # is it empty?
  echo "Usage: $0 NAME"
  exit 1
fi
for i in 1 2 3; do
  echo "Hello $name, round $i"
done

16 Logs and troubleshooting

When something breaks, the logs usually explain why. Traditional text logs live in /var/log — for example /var/log/syslog or /var/log/messages for general system events, and /var/log/auth.log for logins. You follow a growing log in real time with tail -f.

On systemd machines, most logs go to the journal instead: journalctl -xe shows recent entries with explanations, and journalctl -p err filters to errors. For kernel and hardware messages — disks, drivers, USB devices — use dmesg. A good troubleshooting habit: reproduce the problem while watching the relevant log, then read the most recent lines for the error.

sudo tail -f /var/log/syslog     # follow the system log live
journalctl -xe                   # recent journal entries with hints
journalctl -p err --since today  # only today’s error-level messages
dmesg | tail                     # latest kernel / hardware messages

🎓 Certificate of Completion

🔒 Complete every lesson quiz above with 90%+ to unlock your downloadable certificate.