Introduction to Linux
Understand what Linux actually is, how its major components work together, and why it powers modern cloud, containers and DevOps infrastructure.
A complete technical introduction to Linux — from kernel and userspace to distributions, commands, production servers, and real-world DevOps investigation. Build the foundation every cloud and infrastructure engineer needs.
What you will learn
- Understand what the Linux kernel is and what it manages
- Explain the difference between a Linux kernel and a Linux distribution
- Identify the major components of a Linux system: kernel, shell, filesystem, userspace
- Recognise why Linux dominates servers, cloud and DevOps infrastructure
- Run basic Linux commands to identify your system, user and environment
- Apply a structured troubleshooting mindset to investigate Linux server issues
Linux is the kernel at the center of a family of operating systems. A Linux distribution packages that kernel with system utilities, libraries, a package manager and applications to create a complete usable environment. This distinction matters: Ubuntu is a Linux distribution. 'Linux' is the kernel that Ubuntu is built on.
What is this?
At its most fundamental level, Linux is a kernel — the core program that sits between your hardware and every application running on your computer. The kernel manages the CPU, memory, storage devices, network interfaces, and all the input/output that makes a computer useful. Without a kernel, applications would need to talk to hardware directly, which would be chaotic, insecure and practically impossible at scale. The kernel operates in a privileged mode called "kernel space" where it has unrestricted access to hardware. Every other program — your text editor, web server, database, terminal — runs in "user space" with restricted privileges. When an application needs to do something that requires hardware access (reading a file, sending a network packet, allocating memory), it makes a "system call" — a formal request to the kernel, which validates the request, performs the operation safely, and returns the result. On top of the kernel sits the "userspace": system libraries (like glibc, which provides standard C functions), system utilities (like ls, grep, find), a shell (bash, zsh, fish), and applications (nginx, docker, your Python app). Each of these layers communicates with the kernel through a well-defined interface. A "Linux distribution" bundles all of this together: the kernel, a filesystem hierarchy, system utilities, a package manager, a configuration system, and often a default shell and set of applications. Ubuntu, Debian, Red Hat Enterprise Linux (RHEL), Rocky Linux, AlmaLinux, Amazon Linux, and Alpine Linux are all distributions. They share the same Linux kernel but differ in their package managers, release philosophy, default software, and enterprise support. This is why "Linux" technically refers to the kernel, while "Ubuntu" or "Debian" refers to a complete distribution. When someone says they "use Linux," they almost always mean they use a Linux distribution.
What problem does it solve?
- Applications need CPU time — the kernel schedules processes so dozens of services can share one machine without interfering with each other.
- Applications need memory — the kernel allocates and isolates memory so one crashing process cannot corrupt another's data.
- Applications need storage — the kernel presents disks as a unified directory tree through the filesystem, so every program reads and writes files the same way.
- Applications need networking — the kernel manages network interfaces, TCP/IP stacks, and socket connections so applications can communicate across machines.
- Applications need device access — the kernel's device drivers abstract hardware differences, so your code works the same on an NVMe SSD or a network card from any vendor.
- Multiple users need isolation — the kernel enforces permissions so User A cannot read User B's private files without explicit access.
- Processes need accountability — the kernel tracks which process used which resources, enabling monitoring, logging, and resource limiting.
Why do you need it?
- Cost: no per-server licence fees, so organisations save millions across thousands of servers compared to Windows Server.
- Stability: Linux systems regularly run for years without rebooting — kernel updates can often be applied without restarting services.
- Security: strict user privilege separation means a compromised user account does not automatically grant system-wide access. The kernel validates every system call.
- Performance: Linux uses fewer resources for itself, leaving more CPU and memory for your actual workloads — critical on shared servers and containers.
- Ecosystem dominance: Docker, Kubernetes, Terraform, Ansible, Jenkins, GitHub Actions, and virtually every DevOps tool targets Linux as its primary platform.
- Cloud-native: AWS, GCP and Azure all run Linux on the vast majority of their infrastructure. Most container images are based on Linux distributions.
- Transparency: open-source code means anyone can audit, modify and fix the kernel — security vulnerabilities are typically found and patched faster than in proprietary systems.
- Scripting and automation: bash, Python, and shell scripting let you automate repetitive infrastructure tasks in ways that are difficult on Windows.
Mental model
A city government that manages electricity, roads, water and emergency services — never doing the work of citizens itself, but making sure every building gets power, every road is maintained, and no one can steal another building's water supply.
The Linux kernel — managing CPU, memory, storage and networking for every application, keeping them isolated, secure and functional.
The applications (web servers, databases, your terminal) are the citizens. They do their own work, but they rely on the kernel (the city government) to provide infrastructure, enforce rules, and resolve conflicts. Without the government, the city collapses. Without the kernel, the computer is just metal.
Think of a Linux system as four concentric layers: Hardware at the core, the Kernel wrapping it, System Libraries & Utilities on top of that, and Applications on the outside. Every command you type travels inward through these layers: your shell receives it, libraries translate it, the kernel executes it, and hardware carries it out. The result travels back outward to your screen.
How it works
- When you turn on a Linux machine, the bootloader (GRUB) loads the kernel into memory. The kernel initialises hardware drivers, mounts the root filesystem, and launches the first user-space process — typically systemd.
- systemd then starts all system services: networking, logging (journald), SSH, cron, and your application servers. Each runs as a separate process managed by the kernel's scheduler.
- When you open a terminal and type a command, the shell (bash, zsh) reads your input, parses it, and executes the corresponding program. The program makes system calls to the kernel for anything involving hardware.
- The kernel validates each system call against the process's permissions, performs the operation in kernel space, and returns the result to user space. This boundary is what keeps your system secure and stable.
- The filesystem presents everything — files, directories, devices, network shares, kernel state (/proc, /sys) — as files in a single tree, so tools stay uniform and scripts work across distributions.
How a command travels from your keyboard to hardware and back.
Architecture
A Linux system is organised in layers. Each layer has a specific responsibility and communicates with adjacent layers through well-defined interfaces. This separation is what makes Linux both secure and flexible.
At the bottom is hardware — the physical CPU, RAM, disk drives and network cards. Above that is the kernel, which manages all hardware through device drivers and provides system calls as its interface to user space.
System libraries sit above the kernel. These are shared code libraries (like glibc) that applications link against to perform common operations — opening files, allocating memory, creating network connections — without writing raw system calls.
The shell and system utilities form the user-facing layer: bash reads your commands, ls lists files, grep searches text, systemd manages services. These tools use system libraries to talk to the kernel.
Applications — nginx, PostgreSQL, Docker, your Python script — sit at the top, using all the layers below.
The layered architecture of a Linux system.
How it works internally
Key commands
uname -aPrints the kernel name, hostname, kernel version, build date, and architecture. This is the first command to run on any unfamiliar Linux system — it tells you exactly what kernel you are working with.
DevOps use: DevOps engineers need to know the kernel version to verify compatibility with drivers, container runtimes, and security patches.
Linux dev-host 5.15.0-91-generic #101-Ubuntu SMP x86_64 GNU/Linux
Don't confuse 'uname -a' (all info) with 'uname -r' (kernel release only). Use -r when you just need the version number for scripting.
cat /etc/os-releaseDisplays the distribution name, version, codename, and other identifying information. This file is the standard way to detect which Linux distribution you are running.
DevOps use: Automation scripts and CI/CD pipelines read this file to determine which package manager and commands to use — Ubuntu uses apt, RHEL uses dnf, Alpine uses apk.
PRETTY_NAME="Ubuntu 24.04 LTS" NAME="Ubuntu" VERSION_ID="24.04" VERSION="24.04.1 LTS (Noble Numbat)"
Don't assume every Linux system has this file. Some minimal containers or embedded systems may not include it.
hostnamePrints the system's hostname — the human-readable name used to identify the machine on a network.
DevOps use: When managing multiple servers, confirming the hostname before running commands ensures you are executing on the correct machine.
dev-host
whoamiPrints the effective username of the current user. This is critical because many commands behave differently depending on whether you are root or a regular user.
DevOps use: Before running destructive commands (rm -rf, system modifications), always confirm you are not accidentally running as root.
root
idShows the current user's UID (user ID), GID (group ID), and all groups the user belongs to. This is more detailed than whoami — it reveals your actual identity in the permission system.
DevOps use: Debugging permission issues starts with 'id' — if your UID is 0, you are root. If you are not in the right group, you cannot access certain files.
uid=0(root) gid=0(root) groups=0(root),27(sudo)
pwdPrints the current working directory — where you are in the filesystem right now.
DevOps use: Many commands operate on the current directory. Knowing where you are prevents accidentally running operations in the wrong location.
/home/forge
ls -laLists all files (-a includes hidden files starting with .) in long format (-l shows permissions, owner, size, date). This is the most common command for inspecting directory contents.
DevOps use: Quickly verifying file existence, permissions, ownership, and timestamps is a daily task for DevOps engineers.
'ls' alone shows filenames. 'ls -la' shows the full picture including hidden files and permissions — always prefer -la when investigating.
echo $SHELLPrints the path to your current login shell. The shell is the program that interprets your commands — bash, zsh, fish, and others all have different syntax.
DevOps use: Knowing your shell matters when writing scripts — a script written for bash may fail under zsh if it uses bash-specific syntax.
/bin/bash
man <command>Opens the manual page for any command. Every standard Linux command has a man page documenting all flags, examples, and related commands. Press 'q' to quit.
DevOps use: The man page is the authoritative reference for any command — more reliable than Google for understanding edge cases and obscure flags.
Don't skip man pages because they look dense. Start with the EXAMPLES section at the bottom — that is usually the fastest way to learn a command.
Examples
Get a free Linux environment with Docker (Windows, macOS, Linux)
# 1. Install Docker Desktop for your OS# 2. Create a persistent data foldermkdir -p ~/linux-lab # 3. Run a persistent Ubuntu containerdocker run -dit \ --name ubuntu-lab \ --hostname dev-host \ --restart unless-stopped \ --mount type=bind,source="$HOME/linux-lab",target=/data \ ubuntu:latest # 4. Enter the shelldocker exec -it ubuntu-lab bash # 5. Explore your first Linux systemuname -acat /etc/os-releasewhoamils -la /This spins up a disposable Ubuntu machine on your laptop in seconds. The --mount flag persists your work on the host, so nothing is lost when the container is recreated. This is exactly how DevOps engineers prototype and test Linux configurations safely.
When to use it
- Server infrastructure: Linux is the standard for web servers, databases, message queues, and almost all backend infrastructure.
- Containers: Docker and Kubernetes are built on Linux kernel features (namespaces, cgroups). Container images are Linux filesystems.
- Cloud computing: AWS, GCP and Azure run Linux on the vast majority of their instances. Most managed services run Linux internally.
- CI/CD pipelines: GitHub Actions, GitLab CI, Jenkins, and CircleCI all run build jobs on Linux runners.
- Networking equipment: Routers, firewalls, load balancers, and DNS servers frequently run Linux-based operating systems.
- Embedded systems and IoT: Linux's modularity makes it ideal for devices with limited resources — from smart TVs to industrial controllers.
- Automation: shell scripting, Ansible, and infrastructure-as-code tools work best on Linux due to its consistent filesystem and tooling.
- Desktop applications requiring specific Windows-only software (Adobe Creative Suite, Microsoft Office native).
- Gaming where DirectX is required — while Linux gaming has improved dramatically, some titles still require Windows.
- Enterprise environments with strict Microsoft ecosystem dependencies (Active Directory, Exchange, SharePoint).
- Development targeting Windows-specific frameworks like .NET Framework (not .NET Core/5+) or Windows Registry.
- Hardware with poor Linux driver support — some specialised peripherals, WiFi adapters, or GPUs may have limited Linux support.
Alternatives
Best when your workloads depend on .NET Framework, Active Directory, or Windows-specific tooling. Windows Server has stronger integration with Microsoft enterprise software but higher licence costs, larger resource overhead, and less container support.
Common for development workstations but rarely used as a production server. macOS has UNIX compatibility (like Linux) but limited server tooling, no native container support, and Apple's licensing restricts it to Apple hardware.
AUNIX-like operating system with a different kernel. FreeBSD is known for networking performance and security (Netflix, WhatsApp use it for specific workloads). However, its ecosystem is smaller than Linux and most DevOps tooling targets Linux first.
In production
- Nearly every public cloud VM, container image and Kubernetes node runs Linux — server skills transfer directly across AWS, GCP and Azure.
- CI/CD agents (GitHub Actions, GitLab runners, Jenkins) execute build and test jobs on Linux runners — understanding Linux output is essential for debugging builds.
- Managed databases (RDS, Cloud SQL), load balancers (ALB, NLB), and observability stacks (Prometheus, Grafana, ELK) are Linux processes under the hood.
- On-prem infrastructure in banks, telecoms and governments runs RHEL, SUSE or Ubuntu with enterprise support contracts for long-term stability.
- Microservices architectures run inside Linux containers — understanding the host Linux system is critical for debugging networking, storage and performance issues.
- Monitoring and alerting systems (Prometheus, Nagios, Datadog agents) run as Linux services, and their configuration, log files and troubleshooting all require Linux knowledge.
Investigating a slow application server
A DevOps engineer receives an alert: a web application running on a Linux server is responding slowly. Users are reporting 5-second page loads instead of the usual 200ms. The engineer SSHes into the server to investigate.
This investigation follows a structured methodology: identify the system, check resources (CPU, memory, disk), check the application process, check logs, check networking. Later Linux concepts will teach each of these investigation areas in depth. The key insight is that Linux provides all the tools you need — top, df, free, ps, journalctl, ss — to diagnose almost any server issue.
Best practices
- Never use root unnecessarily. Create a regular user and use sudo when elevated privileges are needed — this limits the blast radius of mistakes.
- Read man pages before running unfamiliar commands. The EXAMPLES section at the bottom is usually the fastest way to learn.
- Understand what a command does before running it, especially destructive commands (rm, chmod, kill, dd). If unsure, run it with --help first.
- Keep your systems updated. Regular apt update && apt upgrade (or dnf update) prevents security vulnerabilities and package conflicts.
- Use SSH keys instead of passwords for server access — they are more secure and eliminate password brute-force attacks.
- Monitor resource usage regularly. Tools like top, free, df, and iostat help you catch problems before they become incidents.
- Learn to read logs. journalctl, dmesg, and application logs are your primary source of truth when something breaks.
- Practice in disposable environments. Containers and VMs let you experiment without risking production systems.
- Prefer least privilege. Only grant the permissions a user or service actually needs — never give everything and remove later.
- Never blindly copy production commands from the internet. Understand what they do, test them in staging first, and keep backups.
Common mistakes
- Using root by default and never learning about user permissions — this creates security risks and hides permission-related bugs.
- Applying a Windows mental model: Linux has no drive letters (C:), no .exe files, and paths are case-sensitive (/home is not /Home).
- Running rm -rf without double-checking the path — there is no recycle bin in Linux. Deleted files are gone.
- Skipping package updates and then wondering why new installs fail or why known vulnerabilities are exploitable.
- Assuming all Linux distributions are identical — Ubuntu uses apt, RHEL uses dnf, Alpine uses apk. Commands may differ.
- Not understanding exit codes. An exit code of 0 means success. Any non-zero value means an error occurred — always check $? after important commands.
- Ignoring logs when debugging. The first step in diagnosing any issue should be checking the relevant logs, not guessing.
- Running commands across multiple servers without testing on one first. Always verify on a single server before applying to a fleet.
Common misconceptions
Linux = Ubuntu
Ubuntu is one of many Linux distributions. Linux is the kernel at the center; Ubuntu is a complete operating system built around that kernel, along with its own package manager (apt), release cycle, and default software.
Linux is just the terminal — it has no graphical interface
Linux has excellent graphical desktop environments (GNOME, KDE, XFCE). Most servers run without a GUI for efficiency, but desktop Linux is fully graphical. DevOps engineers typically interact with servers via terminal, but the OS itself supports full graphics.
Docker containers are virtual machines
Containers share the host Linux kernel — they are isolated processes, not full operating systems. This is why containers are lightweight (megabytes, not gigabytes) and fast to start (seconds, not minutes). VMs include their own kernel; containers do not.
Linux commands are identical on every distribution
Core utilities (ls, grep, find) are the same, but system management commands differ. Ubuntu uses apt and systemd, RHEL uses dnf and systemd, Alpine uses apk and OpenRC. Package paths, default configs and service managers vary between distributions.
Everything in Linux is a file, including network connections
Almost everything in Linux is represented as a file — devices (/dev/sda), kernel parameters (/proc, /sys), processes (/proc/PID). However, network connections are managed through the socket API and /proc/net, not as regular filesystem files.
Knowing commands means understanding Linux
Memorising commands is useful but understanding the underlying architecture (kernel, system calls, filesystem hierarchy, process model) is what separates a Linux user from a Linux engineer. Commands are tools; architecture is understanding.
Root is always required for system administration
Most administrative tasks can be done with sudo for specific commands. Running as root permanently is a security risk — if a process is compromised, it has full system access. Use sudo, not root.
Troubleshooting mindset
This methodology applies to any Linux troubleshooting scenario — from a slow application to a failed deployment to a mysterious network issue. DevOps engineers who follow this structured approach solve problems faster and more reliably than those who guess and try random commands.
Common issues
apt: command not foundThe distro uses a different package manager (dnf on RHEL, apk on Alpine, zypper on SUSE) or the container has no package lists.
Detect the distro with cat /etc/os-release, then use the matching manager: dnf install, apk add, zypper install.
W: Failed to fetch ... 404 Not FoundOutdated package lists after a release upgrade or when a mirror is down.
Run apt update && apt upgrade, or verify the source lines in /etc/apt/sources.list match your current release.
Permission denied (publickey)SSH key authentication failed — either the key is not on the server, or the server does not accept key-based auth.
Verify your public key is in ~/.ssh/authorized_keys on the server. Check file permissions: chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys.
bash: /usr/bin/ls: cannot execute binary fileArchitecture mismatch — you are trying to run a binary compiled for a different CPU architecture (e.g., ARM binary on x86).
Run 'uname -m' to check your architecture, then install the correct package for your platform.
No space left on deviceThe filesystem is full — log files, temp files, or application data have consumed all available space.
Run 'df -h' to confirm, then 'du -sh /var/log/*' to find large files. Truncate or remove unnecessary files, then add log rotation.
Debugging tips
- echo $? after any command shows its exit status (0 = success, non-zero = error). This is the first thing to check when a command fails.
- man <command> and <command> --help are the authoritative first places to look when a command behaves unexpectedly.
- dmesg | tail shows recent kernel messages — hardware errors, OOM kills and driver issues appear here before anywhere else.
- type <command> reveals whether you are running a binary, an alias, or a shell builtin — critical for understanding why a command behaves differently than expected.
- strace <command> traces every system call a program makes — invaluable for debugging why a program hangs, fails to open a file, or behaves unexpectedly.
- journalctl -u <service> --since '10 min ago' shows recent logs for a systemd service — faster than grep through log files.
Security considerations
- Never run services as root unless absolutely necessary. Create dedicated users for each service (e.g., 'www-data' for nginx, 'postgres' for PostgreSQL).
- Use SSH keys instead of passwords. Disable password authentication in /etc/ssh/sshd_config to eliminate brute-force attacks.
- Keep systems updated. Regular security patches prevent known vulnerabilities from being exploited. Use unattended-upgrades on Ubuntu for automatic patching.
- Enable the firewall. UFW (Ubuntu) or firewalld (RHEL) should be configured to allow only necessary ports. Default-deny is the safest policy.
- Use sudo instead of su. sudo provides audit logging of who ran which command, while su provides no accountability.
- Understand file permissions. The chmod/chown system is your first line of defence. A world-writable file in /etc is a security vulnerability.
- Monitor authentication logs. /var/log/auth.log (Ubuntu) or /var/log/secure (RHEL) records all login attempts — check them regularly for unauthorized access.
- Apply principle of least privilege. Only grant the exact permissions a user or service needs. Overly broad permissions are the most common security mistake.
Production incident
An application running on a Linux server has become slow. Users report that API responses that normally take 200ms are now taking 5 seconds. The application runs as a Node.js service behind an nginx reverse proxy on an Ubuntu 22.04 server in AWS. You receive an alert at 2 AM and SSH into the server.
Interview checkpoint
Hands-on lab
- Identify the operating system and kernel version
- Identify the current user and their permissions
- Identify the hostname and system uptime
- Inspect the default shell
- Explore the filesystem hierarchy
- Create and verify a file
Explore your first Linux environment
15 min · beginner
Break it yourself
Something is broken. Diagnose the issue using the terminal, then fix it. The sandbox will reset after you complete or give up.
Break it yourself: Permission denied
5 min · beginner
Quick quiz
What exactly is 'Linux'?
Which of the following is NOT managed by the Linux kernel?
A company runs 500 web servers. Why would choosing Linux over Windows Server save significant money?
If an attacker compromises a regular user account on Linux, they automatically have full control of the server.
You SSH into an unfamiliar Linux server. What is the FIRST command you should run to identify what you are working with?
A colleague says they need to 'install Linux' on a server. They ask if it matters which distribution. What is the best answer?
When you type 'ls -la' in a terminal, what is the correct order the command passes through?
You run 'df -h' and see /dev/xvda1 is at 100%. The application starts returning errors. What is the most likely cause and immediate fix?
Cheat sheet
uname -aKernel version and architecturecat /etc/os-releaseDistribution name and versionhostnameMachine hostnameuptimeSystem uptime and load averagesdateCurrent system date and timelsb_release -aDistribution info (if installed)whoamiCurrent logged-in useridUID, GID, and all group membershipsecho $USERUsername from environment variableecho $SHELLCurrent login shell pathlastRecent login historypwdPrint current working directoryls -laList all files with permissions and detailscd /pathChange directorydu -sh *Disk usage per item in current dirdf -hDisk space usage by filesystemfind / -name 'file'Search for a file anywheretouch fileCreate an empty filecp src destCopy a filemv src destMove or rename a filerm fileDelete a file (no recycle bin!)cat filePrint file contentshead -n 10 fileFirst 10 linestail -f /var/log/syslogFollow log file in real-timels -la fileView permissions (rwxr-xr-x)chmod +x fileAdd execute permissionchmod 755 filerwxr-xr-x (owner full, others read+exec)chown user:group fileChange file ownershiptopLive process and resource monitorps auxList all running processesfree -hMemory and swap usagekill PIDSend SIGTERM to a processkill -9 PIDForce-kill (SIGKILL) — use as last resortman <cmd>Full manual page for a command<cmd> --helpQuick usage summaryapropos <topic>Search man pages by keyword