When a Linux host feels slow, the real bottleneck might be CPU, memory, disk I/O, or network behavior. Guessing based on one symptom usually wastes time.
A better approach is the USE method:
top and htoptop
htopThese tools show running processes, CPU usage, memory usage, and load averages. htop is friendlier when installed, but top is usually available by default.
uptimeuptimeThis shows 1, 5, and 15 minute load averages. A high load number can mean many tasks are running or waiting, not only that CPUs are maxed out.
lscpulscpuUse this to learn how many CPUs and cores the system has.
mpstatmpstat -P ALL 1 5This is useful when one core is overloaded while others are mostly idle.
Tip: High load average does not automatically mean CPU exhaustion. Disk waits can also raise load.
Linux uses memory aggressively for cache, so low raw free memory is not always a problem. What matters is whether the system is under pressure.
free -hfree -hLook at total, used, free, and especially available memory.
vmstatvmstat 1 5vmstat shows process activity, memory, swap, I/O, and CPU state over time. Ongoing swap in or swap out activity can suggest memory stress.
/proc/meminfogrep -E 'MemTotal|MemFree|MemAvailable|SwapTotal|SwapFree' /proc/meminfoThis provides detailed kernel memory counters and is useful for scripts or deeper inspection.
Note: A system with low free memory but healthy available memory and little swapping may still be fine.
Storage bottlenecks can make the whole server feel slow even when CPU usage looks reasonable.
iostatiostat -xz 1 5This helps you inspect device utilization, throughput, and wait times. High utilization plus long waits often points to disk pressure.
iotopsudo iotopUse this to find which processes are generating the most disk I/O in real time.
df and dudf -h
du -sh /var/log/*df -h shows filesystem usage, while du shows which directories consume space. Full filesystems can break applications, databases, and package managers.
Network congestion or connection storms can also create performance symptoms.
ss -sss -sThis provides a quick summary of socket states and can help reveal abnormal connection counts.
/proc/net/devcat /proc/net/devThis file shows bytes, packets, drops, and errors for each interface.
sudo iftop
sudo nethogsiftop shows bandwidth by connection. nethogs attributes traffic to processes. They are especially useful when you know the network is busy but not why.
Suppose users report that an API is suddenly slow. A practical first pass could be:
uptime
top
free -h
vmstat 1 5
iostat -xz 1 5
ss -sYou might conclude:
This evidence helps you narrow the bottleneck before making changes.
Avoid these habits:
Performance issues often span multiple subsystems, so keep gathering evidence before acting.
Break Linux performance work into CPU, memory, disk, and network analysis. Use top, uptime, mpstat, and lscpu for CPU; free -h, vmstat, and /proc/meminfo for memory; iostat, iotop, df, and du for storage; and ss -s, /proc/net/dev, iftop, and nethogs for networking.
Most importantly, use a method such as USE so you troubleshoot from evidence rather than instinct.
<MCQExercise exercise={{ id: "linux-performance-q1", title: "Exercise 1: Interpreting load average", description: "Why can a high Linux load average appear even when CPU is not fully busy?", options: [ { id: "a", text: "Because load can include tasks waiting on resources such as disk I/O" }, { id: "b", text: "Because load average measures only firewall rules" }, { id: "c", text: "Because load average is simply the amount of free disk space" }, { id: "d", text: "Because load average is the same thing as swap size" }, ], correctId: "a", explanation: "Load average reflects runnable tasks and some waiting tasks, not just raw CPU usage. A system can show high load when many processes are blocked waiting for I/O.", wrongExplanations: { b: "Firewall rules are unrelated to load average calculation.", c: "Disk space and load average are different system measurements.", d: "Swap size is a memory concept and does not define load average.", }, }} />
<MCQExercise
exercise={{
id: "linux-performance-q2",
title: "Exercise 2: Understanding free memory",
description: "Which memory value is often more useful than raw free memory for a quick Linux health check?",
options: [
{ id: "a", text: "The available memory value from free -h" },
{ id: "b", text: "The inode count from df -i" },
{ id: "c", text: "The port count from ss -s" },
{ id: "d", text: "The username shown by whoami" },
],
correctId: "a",
explanation: "Linux uses memory for caching, so raw free memory can look low even when the system is healthy. The available value gives a better quick estimate of usable memory without heavy pressure.",
wrongExplanations: {
b: "Inodes matter for filesystems, not for interpreting memory availability.",
c: "Socket counts are a networking metric, not a memory availability metric.",
d: "The logged-in username has no bearing on memory interpretation.",
},
}}
/>
<MCQExercise exercise={{ id: "linux-performance-q3", title: "Exercise 3: USE method thinking", description: "In the USE method, what does the S stand for?", options: [ { id: "a", text: "Storage" }, { id: "b", text: "Scheduling" }, { id: "c", text: "Saturation" }, { id: "d", text: "Sessions" }, ], correctId: "c", explanation: "USE stands for Utilization, Saturation, and Errors. Saturation asks whether demand is building up faster than the resource can serve it.", wrongExplanations: { a: "Storage can be a resource you inspect, but it is not what the S stands for in USE.", b: "Scheduling is important in Linux, but it is not the S in this troubleshooting framework.", d: "Sessions are unrelated to the USE acronym.", }, }} />
The average number of processes either running or waiting to run over the last 1, 5 and 15 minutes, and on Linux, unlike some Unixes, it also counts processes blocked on disk I/O. It must be read relative to core count: 4.0 saturates a 4-core box and is light on 16. The three numbers matter as a trend, since a 1-minute figure far above the 15-minute one means the problem is arriving now. nproc gives your core count.
Because Linux uses otherwise idle memory as page cache, and that is the correct behaviour. Unused RAM is wasted RAM. The free column is genuinely unused memory and will always look small on a healthy server; the number to read is available, which accounts for cache the kernel can reclaim instantly. Real memory pressure shows up as swap activity in vmstat 1 (the si and so columns) or as OOM-killer messages in dmesg, not as a low free figure.
ps aux --sort=-%cpu | head and ps aux --sort=-%mem | head give an immediate ranked answer, which is often quicker than reading top. In htop, F6 sorts interactively. For a process you have identified, pidstat -p <pid> 1 shows its usage over time, and for memory specifically pmap -x <pid> or smem distinguishes shared from private memory. Worth doing before concluding a process is large, since ps counts shared libraries against every process using them.
wa in top is the percentage of time CPUs sat idle with at least one outstanding disk request, so it means the CPU had nothing to do but wait. Confirm with iostat -xz 2: %util near 100 and a rising await identify the saturated device, and iotop -o names the processes responsible. The fixes are structural rather than tunable: faster storage, fewer synchronous writes, more caching, or moving the workload. Note that iowait can fall when CPU load rises, because the CPUs are then busy, so never read it alone.
htop for an interactive overview, iotop for per-process disk activity, sysstat for iostat, pidstat and sar, and ncdu for disk usage. sar is the one worth setting up in advance, because it records history, without it, a question like "what did memory do at 03:00 last night" has no answer. Installing these during an incident wastes the time when you least have it, so add them to your base image or configuration management.
2d:["$","$L2e",null,{"tutorial":{"slug":"introduction-to-linux","title":"Introduction to Linux","seoTitle":"What Is Linux? Kernel, Distros and Shell for Beginners","description":"Learn what Linux is: kernel versus distribution versus shell, which distro to learn for DevOps, and why servers and containers overwhelmingly run Linux.","content":"$2f","difficulty":"Easy","duration":"12 min","keywords":["linux tutorial","introduction to linux","linux for beginners","linux kernel vs distro","linux shell basics","devops linux fundamentals","what is linux","linux kernel vs distribution","best linux distro for devops","linux vs windows server","what is a shell linux","bash vs sh","alpine vs ubuntu","linux command line basics","learn linux for docker"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":1,"tableOfContents":[{"id":"what-is-linux","title":"What Is Linux?","level":2},{"id":"kernel-vs-distribution-vs-shell","title":"Kernel vs Distribution vs Shell","level":3},{"id":"why-linux-is-everywhere-in-devops","title":"Why Linux Is Everywhere in DevOps","level":2},{"id":"a-real-example","title":"A Real Example","level":3},{"id":"common-linux-distributions","title":"Common Linux Distributions","level":2},{"id":"ubuntu","title":"Ubuntu","level":3},{"id":"centos-stream","title":"CentOS Stream","level":3},{"id":"alpine","title":"Alpine","level":3},{"id":"linux-on-servers-vms-and-containers","title":"Linux on Servers, VMs, and Containers","level":2},{"id":"gui-vs-command-line","title":"GUI vs Command Line","level":2},{"id":"why-open-source-matters","title":"Why Open Source Matters","level":2},{"id":"what-you-should-remember","title":"What You Should Remember","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-kernel-distribution-and-shell","title":"Exercise 1: Kernel, Distribution, and Shell","level":3},{"id":"exercise-2-why-linux-shows-up-in-devops","title":"Exercise 2: Why Linux shows up in DevOps","level":3},{"id":"exercise-3-choosing-a-distro-for-containers","title":"Exercise 3: Choosing a distro for containers","level":3},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What is the difference between the Linux kernel and a Linux distribution?","answer":"The kernel is the core that manages memory, processes, devices and filesystems. Linux itself is only that kernel. A distribution wraps it with everything else you need to have a usable system: a package manager, an init system, shell utilities, libraries and defaults. Ubuntu, Alpine and Fedora all run the same kernel, so the differences between them are packaging, release cadence and choices such as glibc versus musl. That is why "Linux" in conversation almost always means a distribution."},{"question":"Which Linux distribution should I learn for DevOps?","answer":"Ubuntu, because it is the default on most cloud providers, has the largest body of documentation, and the apt commands you learn transfer to Debian. Add familiarity with a RHEL-family system, Rocky, Alma or CentOS Stream, since regulated and enterprise environments use them and dnf, SELinux and firewalld behave differently enough to matter. Alpine is worth knowing specifically because it dominates container base images, where musl instead of glibc causes real surprises."},{"question":"Do I need to learn the command line, or is a GUI enough?","answer":"The command line, without much qualification. Servers are administered over SSH with no desktop installed, container images contain no GUI, and every automation tool, Ansible, CI pipelines, shell scripts, expresses work as commands. Beyond necessity it is also the only form that is reproducible: a command can be committed to a repository, reviewed and re-run, while a sequence of clicks cannot. A graphical environment is a convenience on your own machine and absent everywhere you will actually work."},{"question":"Why is Linux used for servers and containers rather than Windows?","answer":"Three reasons compound. It is free to run at scale with no per-instance licensing. It is efficient. A minimal install uses a fraction of the memory a Windows Server needs, which directly changes cloud cost. And containers are a Linux kernel feature: namespaces and cgroups are what make them possible, which is why Docker on Windows and macOS runs a Linux virtual machine underneath. The ecosystem followed, so nearly all infrastructure tooling targets Linux first."},{"question":"What is a shell and how does it differ from the terminal?","answer":"The terminal is the window, the shell is the program running inside it that interprets what you type. bash is the long-standing default, zsh ships as standard on macOS, and sh is the minimal POSIX shell that Alpine and most container images provide via ash or dash. The distinction matters in practice: a script starting #!/bin/bash fails on an image with no bash, and features such as [[ ]] and arrays are bash extensions that plain sh does not support."},{"question":"How much Linux do I need before learning Docker or Kubernetes?","answer":"Enough to be comfortable rather than expert: navigating the filesystem, reading and editing files, permissions and ownership, processes and signals, and following logs. Those map directly onto container work. A container is a Linux process, docker exec drops you into a shell, and most failures are permissions, a missing file or a process not listening where you expected. People who skip this find container debugging opaque, because the concepts underneath were never learned."}]},"allTutorials":[{"slug":"introduction-to-linux","title":"Introduction to Linux","seoTitle":"What Is Linux? Kernel, Distros and Shell for Beginners","description":"Learn what Linux is: kernel versus distribution versus shell, which distro to learn for DevOps, and why servers and containers overwhelmingly run Linux.","content":"$30","difficulty":"Easy","duration":"12 min","keywords":"$2d:props:tutorial:keywords","publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":1,"tableOfContents":[{"id":"what-is-linux","title":"What Is Linux?","level":2},{"id":"kernel-vs-distribution-vs-shell","title":"Kernel vs Distribution vs Shell","level":3},{"id":"why-linux-is-everywhere-in-devops","title":"Why Linux Is Everywhere in DevOps","level":2},{"id":"a-real-example","title":"A Real Example","level":3},{"id":"common-linux-distributions","title":"Common Linux Distributions","level":2},{"id":"ubuntu","title":"Ubuntu","level":3},{"id":"centos-stream","title":"CentOS Stream","level":3},{"id":"alpine","title":"Alpine","level":3},{"id":"linux-on-servers-vms-and-containers","title":"Linux on Servers, VMs, and Containers","level":2},{"id":"gui-vs-command-line","title":"GUI vs Command Line","level":2},{"id":"why-open-source-matters","title":"Why Open Source Matters","level":2},{"id":"what-you-should-remember","title":"What You Should Remember","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-kernel-distribution-and-shell","title":"Exercise 1: Kernel, Distribution, and Shell","level":3},{"id":"exercise-2-why-linux-shows-up-in-devops","title":"Exercise 2: Why Linux shows up in DevOps","level":3},{"id":"exercise-3-choosing-a-distro-for-containers","title":"Exercise 3: Choosing a distro for containers","level":3},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What is the difference between the Linux kernel and a Linux distribution?","answer":"The kernel is the core that manages memory, processes, devices and filesystems. Linux itself is only that kernel. A distribution wraps it with everything else you need to have a usable system: a package manager, an init system, shell utilities, libraries and defaults. Ubuntu, Alpine and Fedora all run the same kernel, so the differences between them are packaging, release cadence and choices such as glibc versus musl. That is why "Linux" in conversation almost always means a distribution."},{"question":"Which Linux distribution should I learn for DevOps?","answer":"Ubuntu, because it is the default on most cloud providers, has the largest body of documentation, and the apt commands you learn transfer to Debian. Add familiarity with a RHEL-family system, Rocky, Alma or CentOS Stream, since regulated and enterprise environments use them and dnf, SELinux and firewalld behave differently enough to matter. Alpine is worth knowing specifically because it dominates container base images, where musl instead of glibc causes real surprises."},{"question":"Do I need to learn the command line, or is a GUI enough?","answer":"The command line, without much qualification. Servers are administered over SSH with no desktop installed, container images contain no GUI, and every automation tool, Ansible, CI pipelines, shell scripts, expresses work as commands. Beyond necessity it is also the only form that is reproducible: a command can be committed to a repository, reviewed and re-run, while a sequence of clicks cannot. A graphical environment is a convenience on your own machine and absent everywhere you will actually work."},{"question":"Why is Linux used for servers and containers rather than Windows?","answer":"Three reasons compound. It is free to run at scale with no per-instance licensing. It is efficient. A minimal install uses a fraction of the memory a Windows Server needs, which directly changes cloud cost. And containers are a Linux kernel feature: namespaces and cgroups are what make them possible, which is why Docker on Windows and macOS runs a Linux virtual machine underneath. The ecosystem followed, so nearly all infrastructure tooling targets Linux first."},{"question":"What is a shell and how does it differ from the terminal?","answer":"The terminal is the window, the shell is the program running inside it that interprets what you type. bash is the long-standing default, zsh ships as standard on macOS, and sh is the minimal POSIX shell that Alpine and most container images provide via ash or dash. The distinction matters in practice: a script starting #!/bin/bash fails on an image with no bash, and features such as [[ ]] and arrays are bash extensions that plain sh does not support."},{"question":"How much Linux do I need before learning Docker or Kubernetes?","answer":"Enough to be comfortable rather than expert: navigating the filesystem, reading and editing files, permissions and ownership, processes and signals, and following logs. Those map directly onto container work. A container is a Linux process, docker exec drops you into a shell, and most failures are permissions, a missing file or a process not listening where you expected. People who skip this find container debugging opaque, because the concepts underneath were never learned."}]},{"slug":"linux-filesystem","title":"Linux Filesystem","seoTitle":"Linux Filesystem Hierarchy: What /etc, /var and /usr Are For","description":"Learn the Linux directory tree: what /etc, /var and /usr hold, /tmp versus /var/tmp, virtual /proc and /sys, and the places where disks tend to fill up.","content":"$31","difficulty":"Easy","duration":"15 min","keywords":["linux filesystem","fhs tutorial","linux directories","absolute vs relative paths","linux path basics","filesystem hierarchy standard","linux filesystem hierarchy","etc var usr directories","linux directory structure","proc and sys filesystem","tmp vs var/tmp","where to install software linux","opt vs usr/local","linux disk full var/log","linux root directory"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":2,"tableOfContents":[{"id":"understanding-the-linux-filesystem","title":"Understanding the Linux Filesystem","level":2},{"id":"what-is-the-filesystem-hierarchy-standard","title":"What Is the Filesystem Hierarchy Standard?","level":2},{"id":"the-root-directory-","title":"The Root Directory /","level":2},{"id":"important-linux-directories","title":"Important Linux Directories","level":2},{"id":"etc","title":"/etc","level":3},{"id":"var","title":"/var","level":3},{"id":"tmp","title":"/tmp","level":3},{"id":"home","title":"/home","level":3},{"id":"usr","title":"/usr","level":3},{"id":"proc","title":"/proc","level":3},{"id":"absolute-vs-relative-paths","title":"Absolute vs Relative Paths","level":2},{"id":"absolute-paths","title":"Absolute Paths","level":3},{"id":"relative-paths","title":"Relative Paths","level":3},{"id":"special-path-shortcuts","title":"Special Path Shortcuts","level":3},{"id":"reading-the-filesystem-like-a-devops-engineer","title":"Reading the Filesystem Like a DevOps Engineer","level":2},{"id":"why-filesystem-knowledge-matters","title":"Why Filesystem Knowledge Matters","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-finding-configuration-files","title":"Exercise 1: Finding configuration files","level":3},{"id":"exercise-2-reading-proc-correctly","title":"Exercise 2: Reading /proc correctly","level":3},{"id":"exercise-3-spotting-a-relative-path","title":"Exercise 3: Spotting a relative path","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What is the Filesystem Hierarchy Standard?","answer":"A specification defining what each top-level directory is for, which is why /etc holds configuration on Ubuntu, Alpine and Fedora alike. It means knowledge transfers between distributions and tooling can make safe assumptions about where things live. Compliance is not absolute. Distributions differ in details, and several have merged /bin into /usr/bin via symlinks, but the broad structure is dependable enough to navigate an unfamiliar system."},{"question":"What is the difference between /etc, /var and /usr?","answer":"/etc holds system-wide configuration: text files you edit, and the first place to look when changing how something behaves. /var holds variable data the system writes during operation. Logs in /var/log, databases and container images in /var/lib, queued mail and print jobs in /var/spool, and it is what grows. /usr holds installed programs and their static supporting files, managed by the package manager and not normally edited by hand."},{"question":"What is the difference between /tmp and /var/tmp?","answer":"/tmp is for short-lived files and is cleared on reboot, and on many modern systems it is a tmpfs living in RAM, which means writing a large file there consumes memory and disappears entirely on restart. /var/tmp is also temporary but is expected to survive a reboot, making it the right choice for a long-running job's intermediate files. Both are world-writable with the sticky bit set, so users cannot delete each other's files."},{"question":"What are /proc and /sys?","answer":"Virtual filesystems that expose kernel state as readable files, occupying no disk space at all. /proc is mostly per-process information, /proc/<pid>/ describes a running process, plus system-wide values such as /proc/meminfo and /proc/cpuinfo. /sys exposes devices and kernel parameters, and writing to files there changes settings at runtime. This is why commands like free and ps work: they read and format these files rather than asking the kernel through a special interface."},{"question":"Where should I install software that does not come from a package?","answer":"/opt for a self-contained third-party application that keeps its own directory tree, and /usr/local when you are installing something that follows the usual bin, lib, share layout, /usr/local/bin is on PATH by default and is the conventional place for a compiled binary. Avoid writing into /usr/bin yourself, because that belongs to the package manager and your file will eventually be overwritten or conflict with an upgrade."},{"question":"Which directories should I check first when a disk fills up?","answer":"/var/log and /var/lib, in that order. Logs grow without limit when rotation is missing or misconfigured, and /var/lib/docker or /var/lib/containerd accumulates images, layers and volumes surprisingly fast on a build host. sudo du -sh /var/* | sort -h narrows it in one command. If df reports a full disk but du does not account for it, look for a deleted file still held open by a process with sudo lsof +L1."}]},{"slug":"linux-navigation","title":"Linux Navigation","seoTitle":"Linux Navigation: pwd, ls, cd, man and Command Not Found","description":"Move around Linux with confidence: absolute versus relative paths, reading ls -l output, which versus type, man pages and fixing command not found errors.","content":"$32","difficulty":"Easy","duration":"12 min","keywords":["linux navigation","pwd ls cd tutorial","linux command line basics","man and help linux","which whereis tree","linux beginner commands","linux navigation commands","ls -l columns explained","absolute vs relative path","cd - previous directory","which vs whereis vs type","how to read man pages","linux command not found PATH","pwd command","ls -lah","linux terminal basics"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":3,"tableOfContents":[{"id":"why-navigation-skills-matter","title":"Why Navigation Skills Matter","level":2},{"id":"finding-your-current-location-with-pwd","title":"Finding Your Current Location with pwd","level":2},{"id":"listing-files-with-ls","title":"Listing Files with ls","level":2},{"id":"changing-directories-with-cd","title":"Changing Directories with cd","level":2},{"id":"visualizing-structure-with-tree","title":"Visualizing Structure with tree","level":2},{"id":"identifying-file-types-with-file","title":"Identifying File Types with file","level":2},{"id":"locating-commands-with-which-and-whereis","title":"Locating Commands with which and whereis","level":2},{"id":"reading-documentation-with-man","title":"Reading Documentation with man","level":2},{"id":"using-built-in-help-with-help","title":"Using Built-In Help with help","level":2},{"id":"a-small-hands-on-workflow","title":"A Small Hands-On Workflow","level":2},{"id":"common-beginner-mistakes","title":"Common Beginner Mistakes","level":2},{"id":"forgetting-the-current-directory","title":"Forgetting the Current Directory","level":3},{"id":"ignoring-hidden-files","title":"Ignoring Hidden Files","level":3},{"id":"not-reading-built-in-docs","title":"Not Reading Built-In Docs","level":3},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-listing-hidden-entries","title":"Exercise 1: Listing hidden entries","level":3},{"id":"exercise-2-choosing-which-versus-whereis","title":"Exercise 2: Choosing which versus whereis","level":3},{"id":"exercise-3-getting-help-for-built-ins","title":"Exercise 3: Getting help for built-ins","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What is the difference between an absolute and a relative path?","answer":"An absolute path starts at the root and is unambiguous wherever you run it, /var/log/nginx/access.log. A relative path is interpreted from your current directory, so logs/access.log means something different depending on where you are. Relative paths are fine when typing interactively; use absolute paths in scripts, cron jobs and systemd units, because those run from a working directory you did not choose and "file not found" for a path that plainly exists is nearly always this."},{"question":"What do the columns in ls -l mean?","answer":"Left to right: the permission string, link count, owner, group, size in bytes, modification time, and name. The permission string's first character is the file type, - for a regular file, d for a directory, l for a symlink, followed by three groups of rwx for user, group and other. Add -h for human-readable sizes and -a to include hidden files, which is why ls -lah is the form worth committing to muscle memory."},{"question":"What does cd - do?","answer":"Returns you to the previous directory, toggling between two locations. Invaluable when moving repeatedly between a config directory and a log directory. cd with no argument goes home, and cd .. goes up one level. For deeper movement, pushd and popd maintain a stack of directories, and dirs -v lists it. Most of the time cd - plus tab completion covers everything you need."},{"question":"What is the difference between which, whereis and type?","answer":"which searches your PATH and prints the executable that would run. whereis additionally locates the binary, source and man page from a system database. type is a shell builtin and the most informative, because it reveals things which cannot see. Whether the name is an alias, a shell function, or a builtin. When which python says one thing and the command behaves like another, type python explains why."},{"question":"How do I read a man page effectively?","answer":"Man pages open in less, so /pattern searches, n and N move between matches, g and G jump to start and end, and q quits. Rather than reading top to bottom, search for the flag you care about, /--exclude, since the options section is where the answers are. man -k <keyword> searches all page descriptions when you do not know the command name. tldr is worth installing for a short page of practical examples instead of the full reference."},{"question":"Why does my terminal say "command not found" for a program I installed?","answer":"The program is not in a directory on your PATH. Check with echo $PATH and confirm where it actually landed using ls /usr/local/bin or find / -name <program> 2>/dev/null. Fix it by adding the directory in ~/.bashrc with export PATH="$PATH:/opt/tool/bin", then opening a new shell or running source ~/.bashrc. The other common cause is installing with a package manager whose install location is not on PATH, such as a user-level pip install putting binaries in ~/.local/bin."}]},{"slug":"linux-file-operations","title":"Linux File Operations","seoTitle":"Linux File Commands: cp, mv, rm, find and the Trailing Slash","description":"Copy, move, delete and read files safely on Linux: why rm has no undo, cp -r versus cp -a, the trailing-slash trap, find by name and size, less versus tail.","content":"$33","difficulty":"Easy","duration":"15 min","keywords":["linux file operations","cp mv rm tutorial","linux links","head tail less cat","mkdir touch ln","file management linux","cp -r vs cp -a","rm undo linux","linux find command by name size","mkdir -p","cat vs less vs tail","tail -F log rotation","rsync trailing slash","linux copy directory permissions","rm -rf safety"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":4,"tableOfContents":[{"id":"working-with-files-safely","title":"Working with Files Safely","level":2},{"id":"creating-files-and-directories","title":"Creating Files and Directories","level":2},{"id":"copying-files-with-cp","title":"Copying Files with cp","level":2},{"id":"moving-and-renaming-with-mv","title":"Moving and Renaming with mv","level":2},{"id":"removing-with-rm","title":"Removing with rm","level":2},{"id":"reading-file-content","title":"Reading File Content","level":2},{"id":"cat","title":"cat","level":3},{"id":"head","title":"head","level":3},{"id":"tail","title":"tail","level":3},{"id":"less","title":"less","level":3},{"id":"links-hard-links-and-symbolic-links","title":"Links: Hard Links and Symbolic Links","level":2},{"id":"hard-links","title":"Hard Links","level":3},{"id":"symbolic-links","title":"Symbolic Links","level":3},{"id":"a-practical-example","title":"A Practical Example","level":2},{"id":"choosing-the-right-command","title":"Choosing the Right Command","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-creating-directory-trees","title":"Exercise 1: Creating directory trees","level":3},{"id":"exercise-2-following-a-growing-file","title":"Exercise 2: Following a growing file","level":3},{"id":"exercise-3-using-flexible-links","title":"Exercise 3: Using flexible links","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"Is there any way to undo rm in Linux?","answer":"Not for practical purposes. rm unlinks the file immediately with no trash directory, and while the blocks may survive on disk until overwritten, recovery tools such as extundelete or testdisk are unreliable on a mounted filesystem and rarely worth attempting. Prevention is the whole answer: alias rm to rm -i for interactive confirmation, use a trash utility such as trash-cli for interactive work, and keep backups. Before any rm -rf, read the path out loud. Most accidents are a stray space or an unquoted variable."},{"question":"What is the difference between cp -r and cp -a?","answer":"-r copies a directory recursively but resets ownership to you and updates timestamps to now. -a (archive) preserves permissions, ownership, timestamps and symlinks, which is what you want when copying system files, a web root, or anything where metadata matters. A common symptom of using -r is a service refusing to start after a copy because files it needs are now owned by the wrong user. When in doubt on system files, use -a."},{"question":"Why did cp put my files in the wrong place?","answer":"Almost always the trailing slash on the source. cp -a dir dest/ copies the directory itself, producing dest/dir; cp -a dir/. dest/ copies its contents into dest. rsync has the same distinction, where rsync -a src/ dest/ syncs contents and rsync -a src dest/ creates dest/src. The other cause is a destination that does not exist, in which case cp treats the last argument as a new filename rather than a directory."},{"question":"How do I find files by name or size?","answer":"find /path -name ".log" matches by name, -iname case-insensitively, and -type f restricts to regular files. find /var -size +100M finds large files, and -mtime -7 those modified in the last week. Combine with -exec to act on results, find . -name ".tmp" -delete, but always run the find alone first to see what it matches, because -delete and -exec rm are as unforgiving as rm itself. For searching contents rather than names, use grep -r or rg."},{"question":"What is the difference between cat, less, head and tail?","answer":"cat prints the whole file to your terminal, which is fine for something small and unhelpful for a 2 GB log. less pages through it without loading it all, supports / to search, and is the right default for anything large. head -n 20 shows the first lines and tail -n 50 the last, and tail -F follows a file as it grows, surviving log rotation, which the plain -f does not."},{"question":"How do I create a file or directory tree in one command?","answer":"touch file.txt creates an empty file or updates an existing one's timestamp. mkdir -p a/b/c creates the whole path, creating parents as needed and succeeding silently if it already exists, which is what makes it safe in scripts, where plain mkdir errors on an existing directory. Brace expansion handles several at once: mkdir -p project/{src,tests,docs} creates all three subdirectories in one go."}]},{"slug":"linux-text-processing","title":"Linux Text Processing","seoTitle":"Linux grep, sed and awk: Text Processing With Examples","description":"Use grep, sed, awk, sort and uniq for real work: pick the right tool for each question, avoid the sed -i portability trap and see why errors vanish in pipes.","content":"$34","difficulty":"Medium","duration":"20 min","keywords":["linux text processing","grep awk sed tutorial","pipes and redirection linux","sort uniq wc cut","linux regex basics","log analysis commands","grep sed awk","sed replace text in file","awk print column","sort uniq -c","grep recursive search","cut vs awk","sed -i macos linux","2>&1 redirect stderr","linux text processing commands","count occurrences log file"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":5,"tableOfContents":[{"id":"why-text-processing-matters-in-devops","title":"Why Text Processing Matters in DevOps","level":2},{"id":"searching-with-grep","title":"Searching with grep","level":2},{"id":"basic-regular-expressions","title":"Basic Regular Expressions","level":3},{"id":"selecting-fields-with-cut","title":"Selecting Fields with cut","level":2},{"id":"sorting-and-deduplicating","title":"Sorting and Deduplicating","level":2},{"id":"counting-with-wc","title":"Counting with wc","level":2},{"id":"pattern-based-processing-with-awk","title":"Pattern-Based Processing with awk","level":2},{"id":"editing-streams-with-sed","title":"Editing Streams with sed","level":2},{"id":"in-place-editing","title":"In-Place Editing","level":3},{"id":"pipes-and-redirection","title":"Pipes and Redirection","level":2},{"id":"a-real-log-analysis-workflow","title":"A Real Log Analysis Workflow","level":2},{"id":"when-to-use-which-tool","title":"When to Use Which Tool","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-anchoring-a-grep-search","title":"Exercise 1: Anchoring a grep search","level":3},{"id":"exercise-2-splitting-fields-with-cut","title":"Exercise 2: Splitting fields with cut","level":3},{"id":"exercise-3-counting-repeated-values","title":"Exercise 3: Counting repeated values","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"When should I use grep, sed or awk?","answer":"grep selects lines matching a pattern and does nothing else. Reach for it when the question is "which lines". sed is a stream editor for substitution and deletion, so "change this to that" is its job, usually sed 's/old/new/g'. awk splits each line into fields and can do arithmetic and conditionals, so it wins whenever you care about columns, awk '$3 > 100 {print $1}'. If you find yourself building something with three pipes and a conditional, that is usually one awk program."},{"question":"How do I replace text in a file from the command line?","answer":"sed -i 's/old/new/g' file.txt, -i edits in place, s substitutes, and g replaces every occurrence on each line rather than just the first. There is one portability trap: GNU sed on Linux accepts bare -i, while BSD sed on macOS requires a backup suffix, so the same command needs sed -i '' 's/old/new/g' there. Scripts that must run on both should use perl -pi -e 's/old/new/g', which behaves identically everywhere."},{"question":"What is the difference between cut and awk for extracting columns?","answer":"cut -d' ' -f3 treats every single delimiter as a boundary, so two consecutive spaces produce an empty field, which makes it unreliable on command output aligned with variable whitespace. awk '{print $3}' treats any run of whitespace as one separator by default, which is almost always what you want for ps, df or log output. cut is the better tool for genuinely delimited data such as CSV or /etc/passwd, where the delimiter is exactly one character."},{"question":"How do I count unique occurrences in a log file?","answer":"sort file | uniq -c | sort -rn | head. The first sort is mandatory, because uniq only collapses adjacent duplicates and silently does nothing otherwise, that is the most common mistake with it. uniq -c prefixes each line with its count, and sort -rn orders by that count descending. Combined with awk to pull out a field, it answers most log questions: awk '{print $1}' access.log | sort | uniq -c | sort -rn | head gives your top client IPs."},{"question":"How do I search recursively through a directory?","answer":"grep -rn "pattern" ., r recurses, n adds line numbers so the output is actionable. Add -i for case-insensitive and --include="*.py" to limit by file type. grep -rl lists only the matching filenames, which is what you want when feeding results into another command. For large repositories, ripgrep (rg) is considerably faster and respects .gitignore by default, which usually removes more noise than any set of --exclude flags."},{"question":"Why does my error message disappear when I pipe a command?","answer":"Because a pipe carries stdout only, and errors go to stderr. command | grep error therefore filters the normal output and lets the actual error print straight to your terminal, unfiltered. Redirect stderr into stdout first with command 2>&1 | grep error. The order matters: 2>&1 >file and >file 2>&1 do different things, because redirections are processed left to right. The second is the one that sends both to the file."}]},{"slug":"linux-permissions","title":"Linux Permissions","seoTitle":"Linux File Permissions: chmod, chown, Octal Modes and umask","description":"Understand Linux permissions: rwx for user, group and other, octal modes like 755 and 644, chmod versus chown, setuid, the sticky bit and umask defaults.","content":"$35","difficulty":"Medium","duration":"18 min","keywords":["linux permissions","chmod chown tutorial","rwx octal notation","setuid setgid sticky bit","linux umask","file ownership linux","chmod 755","chmod 644","chmod vs chown","linux file permissions explained","octal permissions","umask linux","chmod 777 security","permission denied linux"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":6,"tableOfContents":[{"id":"why-permissions-matter","title":"Why Permissions Matter","level":2},{"id":"user-group-and-other","title":"User, Group, and Other","level":2},{"id":"understanding-rwx-notation","title":"Understanding rwx Notation","level":2},{"id":"octal-notation","title":"Octal Notation","level":2},{"id":"changing-modes-with-chmod","title":"Changing Modes with chmod","level":2},{"id":"changing-ownership-with-chown-and-chgrp","title":"Changing Ownership with chown and chgrp","level":2},{"id":"special-permission-bits","title":"Special Permission Bits","level":2},{"id":"setuid","title":"setuid","level":3},{"id":"setgid","title":"setgid","level":3},{"id":"sticky-bit","title":"Sticky Bit","level":3},{"id":"understanding-umask","title":"Understanding umask","level":2},{"id":"real-world-scenarios","title":"Real-World Scenarios","level":2},{"id":"a-script-will-not-run","title":"A Script Will Not Run","level":3},{"id":"a-web-app-cannot-read-a-config-file","title":"A Web App Cannot Read a Config File","level":3},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-choosing-a-restrictive-file-mode","title":"Exercise 1: Choosing a restrictive file mode","level":3},{"id":"exercise-2-using-setgid-on-directories","title":"Exercise 2: Using setgid on directories","level":3},{"id":"exercise-3-predicting-umask-results","title":"Exercise 3: Predicting umask results","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What does chmod 755 mean?","answer":"Each digit is one class, user, group, other, and each is the sum of read (4), write (2) and execute (1). So 755 is rwxr-xr-x: the owner can read, write and execute; group and other can read and execute but not write. It is the standard mode for directories and for executable scripts. The other number you need is 644 (rw-r--r--), the standard for ordinary files, which is 755 without the execute bits."},{"question":"What is the difference between chmod and chown?","answer":"chmod changes permissions. What the owner, group and everyone else are allowed to do. chown changes ownership, which user and group those permissions apply to. They solve different halves of the same problem, and picking the wrong one is a common source of frustration: if a service cannot write to its data directory, the fix is usually chown to the service's user rather than loosening the mode with chmod."},{"question":"Why do permissions mean something different on a directory?","answer":"Because a directory is a list of names, not content. Read (r) lets you list what is inside; write (w) lets you create, rename and delete entries, which is why you can delete a file you cannot write to, as long as you can write to its directory. Execute (x) is the right to traverse the directory, to reach anything inside it. A directory with r but no x lets you see the file names and access none of them, which produces confusing "permission denied" errors on paths that clearly exist."},{"question":"Is chmod 777 ever the right answer?","answer":"Effectively never. It makes a file readable, writable and executable by every account on the system, so any compromised process can rewrite it, and if it is a script something privileged runs, that is a direct path to privilege escalation. It is also usually treating the symptom: the real question is which user needs the access, answered with chown or by adding that user to the right group. The one defensible use is a deliberately shared scratch directory, and then it needs the sticky bit as well."},{"question":"What are setuid, setgid and the sticky bit?","answer":"Three extra bits beyond rwx. setuid (chmod u+s) makes an executable run as its owner rather than the user invoking it. How /usr/bin/passwd can edit /etc/shadow on your behalf, and dangerous on anything else. setgid on a directory makes new files inherit the directory's group, which is the clean way to share a folder between team members. The sticky bit (chmod +t) on a world-writable directory restricts deletion to each file's owner, which is why /tmp is safe to share."},{"question":"How do umask and default permissions work?","answer":"umask is a mask of bits to remove from the defaults when a file is created: 666 for files and 777 for directories. The common default of 022 therefore yields 644 for files and 755 for directories. Set a stricter 077 and new files are readable only by you, which suits a multi-user server. Check the current value with umask and set it in ~/.bashrc for a user or /etc/profile for everyone; note that it affects only newly created files, not existing ones."}]},{"slug":"linux-users-groups","title":"Linux Users and Groups","seoTitle":"Linux Users and Groups: useradd, usermod -aG and sudo","description":"Manage Linux accounts safely: useradd versus adduser, why usermod -aG needs a new login, the destructive -G mistake, sudo versus su and the account files.","content":"$36","difficulty":"Medium","duration":"15 min","keywords":["linux users groups","useradd usermod userdel","sudo su visudo","etc passwd shadow","linux account management","groupadd passwd id whoami","linux users and groups","useradd vs adduser","usermod -aG","sudo vs su","etc/passwd etc/shadow","add user to sudo group","linux group not taking effect","visudo sudoers","delete linux user","id and groups command"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":7,"tableOfContents":[{"id":"why-user-management-matters","title":"Why User Management Matters","level":2},{"id":"core-identity-commands","title":"Core Identity Commands","level":2},{"id":"creating-and-removing-users","title":"Creating and Removing Users","level":2},{"id":"modifying-users-with-usermod","title":"Modifying Users with usermod","level":2},{"id":"working-with-groups","title":"Working with Groups","level":2},{"id":"sudo-vs-su","title":"sudo vs su","level":2},{"id":"sudo","title":"sudo","level":3},{"id":"su","title":"su","level":3},{"id":"important-account-files","title":"Important Account Files","level":2},{"id":"etcpasswd","title":"/etc/passwd","level":3},{"id":"etcshadow","title":"/etc/shadow","level":3},{"id":"managing-sudo-access","title":"Managing Sudo Access","level":2},{"id":"real-world-scenarios","title":"Real-World Scenarios","level":2},{"id":"granting-docker-access","title":"Granting Docker Access","level":3},{"id":"creating-a-deployment-account","title":"Creating a Deployment Account","level":3},{"id":"best-practices","title":"Best Practices","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-preserving-existing-groups","title":"Exercise 1: Preserving existing groups","level":3},{"id":"exercise-2-distinguishing-passwd-and-shadow","title":"Exercise 2: Distinguishing passwd and shadow","level":3},{"id":"exercise-3-avoiding-broken-sudoers-files","title":"Exercise 3: Avoiding broken sudoers files","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What is the difference between useradd and adduser?","answer":"useradd is the low-level binary present on every distribution; it does exactly what you tell it and nothing more, so without flags it creates no home directory and sets no password. adduser is a Perl wrapper on Debian and Ubuntu that asks interactively, creates the home directory, copies /etc/skel, and sets up a matching group, which is what you usually want on a workstation. Scripts should use useradd with explicit flags (-m -s /bin/bash) because it is portable and non-interactive."},{"question":"Why does usermod -aG not take effect until I log out?","answer":"Group membership is attached to your session at login and is not re-read afterwards, so a shell that was already open keeps the group list it started with no matter what you change. Log out and back in, or run newgrp <group> to start a shell with the new membership immediately. For a systemd service, restart the service rather than the session. This is the single most common "the command worked but nothing changed" moment in Linux administration."},{"question":"What is the difference between -aG and -G in usermod?","answer":"-aG appends the listed groups to the user's existing secondary groups. -G replaces them entirely, so usermod -G docker alice removes Alice from every other secondary group she was in, including sudo, which can lock an administrator out of their own machine. The -a is only meaningful with -G, and omitting it is a genuinely destructive mistake. Check the result with groups alice or id alice immediately afterwards."},{"question":"What is the difference between sudo and su?","answer":"sudo runs a single command as another user, defaulting to root, authenticating with your own password and logging what was run. su switches to another user for an entire session and needs that user's password. sudo is preferable for administration: nobody needs to know the root password, permissions can be granted per command in sudoers, and every invocation is recorded in the auth log. Where you genuinely want a root shell, sudo -i gives one with the same audit trail."},{"question":"What is the difference between /etc/passwd, /etc/shadow and /etc/group?","answer":"/etc/passwd holds account records, username, UID, GID, home directory, shell, and is world-readable, because ordinary programs need to map UIDs to names. Password hashes were historically in that file, which meant anyone could copy them and attack offline, so they moved to /etc/shadow, readable only by root, along with expiry and ageing fields. /etc/group lists groups and their secondary members. Edit them with usermod, chage and gpasswd rather than by hand."},{"question":"How do I give a user sudo access?","answer":"Add them to the administrative group: usermod -aG sudo alice on Debian and Ubuntu, or wheel on RHEL-family systems. They must log out and back in for it to apply. For narrower access, add a file under /etc/sudoers.d/ granting specific commands, alice ALL=(ALL) NOPASSWD: /bin/systemctl restart myapp, which is better practice than full root for a service operator. Always edit sudoers files with visudo (or visudo -f), since it validates the syntax and a malformed sudoers file locks everyone out."}]},{"slug":"linux-process-management","title":"Linux Process Management","seoTitle":"Linux Process Management: ps, top, kill and Signals","description":"Find, watch and stop Linux processes: use ps and top, send SIGTERM before SIGKILL, spot zombie states, read load average and find which process owns a port.","content":"$37","difficulty":"Medium","duration":"20 min","keywords":["linux process management","ps top htop kill signals","nohup jobs bg fg","nice renice tutorial","process states linux","background jobs bash","kill vs kill -9","SIGTERM SIGKILL","find process using port linux","zombie process linux","linux load average explained","nohup vs disown","ps aux","uninterruptible sleep D state","lsof port"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":8,"tableOfContents":[{"id":"what-is-a-process","title":"What Is a Process?","level":2},{"id":"listing-processes-with-ps","title":"Listing Processes with ps","level":2},{"id":"watching-processes-live-with-top-and-htop","title":"Watching Processes Live with top and htop","level":2},{"id":"stopping-processes-with-kill","title":"Stopping Processes with kill","level":2},{"id":"process-priority-with-nice-and-renice","title":"Process Priority with nice and renice","level":2},{"id":"jobs-backgrounding-and-foreground-control","title":"Jobs, Backgrounding, and Foreground Control","level":2},{"id":"keeping-processes-alive-with-nohup","title":"Keeping Processes Alive with nohup","level":2},{"id":"process-states","title":"Process States","level":2},{"id":"a-practical-troubleshooting-example","title":"A Practical Troubleshooting Example","level":2},{"id":"best-practices","title":"Best Practices","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-choosing-the-first-stop-signal","title":"Exercise 1: Choosing the first stop signal","level":3},{"id":"exercise-2-tracking-background-jobs","title":"Exercise 2: Tracking background jobs","level":3},{"id":"exercise-3-surviving-shell-disconnects","title":"Exercise 3: Surviving shell disconnects","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What is the difference between kill and kill -9?","answer":"Plain kill <pid> sends SIGTERM, a request to shut down that the process can catch, so it can finish writing a file, close connections and release locks. kill -9 sends SIGKILL, which the kernel enforces and the process cannot catch or ignore, so it stops mid-operation with no cleanup. That makes -9 a last resort rather than a default: reaching for it first is how you get corrupt files and stale lock files. Try SIGTERM, wait a few seconds, then escalate."},{"question":"How do I find which process is using a port?","answer":"sudo ss -tlnp | grep :8080 lists listening sockets with the owning process and PID, and is the modern replacement for netstat -tlnp. sudo lsof -i :8080 gives the same answer with more detail about open files. The sudo matters, without it you see the ports but not which process owns them, because that information belongs to other users. Once you have the PID, ps -p <pid> -o pid,user,cmd shows the full command line."},{"question":"What is a zombie process and how do I kill it?","answer":"A zombie has already terminated; what remains is an entry in the process table holding its exit status, waiting for its parent to read it with wait(). You cannot kill it, because there is nothing running. Signals to a zombie do nothing. The fix is the parent: if it is buggy and not reaping children, restart it, at which point the zombies are re-parented to init and cleaned up immediately. A handful of zombies is harmless; thousands means a parent process with a real bug."},{"question":"Why can't I kill a process even with kill -9?","answer":"It is in uninterruptible sleep, shown as state D in ps. The process is blocked inside a kernel call, typically waiting on disk or a hung NFS mount, and signals are not delivered until that call returns. SIGKILL is queued rather than ignored, and takes effect the moment the I/O completes or times out. Fix the underlying cause: check dmesg for storage errors and unmount or remount the stuck filesystem. A reboot is sometimes the only route out."},{"question":"What is the difference between nohup, disown and screen or tmux?","answer":"nohup command & starts a process immune to SIGHUP, so it survives your shell exiting, with output redirected to nohup.out. disown does the same for a job you have already backgrounded. screen and tmux go further by giving the process a persistent terminal you can detach from and reattach to later, which is what you want for anything interactive or long enough that you will need to check on it. For a service that must survive reboots, none of these is right. Write a systemd unit."},{"question":"What do load averages actually mean?","answer":"The three numbers from uptime are the average number of processes runnable or waiting on I/O over the last 1, 5 and 15 minutes. They must be read against your core count: a load of 4.0 saturates a 4-core machine and is comfortable on 16. The trend across the three matters more than any single figure. A first number well above the third means load is climbing. Note that on Linux the figure includes processes blocked on disk, so high load with low CPU usage usually points at I/O rather than compute."}]},{"slug":"linux-systemd","title":"Linux systemd Basics","seoTitle":"systemd and systemctl Basics: Services, Units and journalctl","description":"Manage Linux services with systemctl: start versus enable, daemon-reload after edits, writing a unit file, what Type= controls and reading logs.","content":"$38","difficulty":"Medium","duration":"18 min","keywords":["linux systemd","systemctl tutorial","journalctl basics","systemd unit file","linux service management","systemd targets","systemd","systemctl start vs enable","systemctl daemon-reload","journalctl -u service","systemd Type=simple notify","systemctl edit override","systemd Restart=on-failure","create systemd service","systemctl is-enabled"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":9,"tableOfContents":[{"id":"what-is-systemd","title":"What Is systemd?","level":2},{"id":"understanding-units-and-targets","title":"Understanding Units and Targets","level":2},{"id":"managing-services-with-systemctl","title":"Managing Services with systemctl","level":2},{"id":"enabling-and-disabling-at-boot","title":"Enabling and Disabling at Boot","level":2},{"id":"reading-logs-with-journalctl","title":"Reading Logs with journalctl","level":2},{"id":"writing-a-simple-unit-file","title":"Writing a Simple Unit File","level":2},{"id":"understanding-key-unit-sections","title":"Understanding Key Unit Sections","level":2},{"id":"unit","title":"[Unit]","level":3},{"id":"service","title":"[Service]","level":3},{"id":"install","title":"[Install]","level":3},{"id":"practical-troubleshooting-flow","title":"Practical Troubleshooting Flow","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-start-versus-enable","title":"Exercise 1: Start versus enable","level":3},{"id":"exercise-2-filtering-the-journal","title":"Exercise 2: Filtering the journal","level":3},{"id":"exercise-3-making-systemd-notice-changes","title":"Exercise 3: Making systemd notice changes","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What is the difference between systemctl start and systemctl enable?","answer":"start runs the service right now and does nothing about future boots. enable creates the symlink that makes systemd start it at boot and does nothing right now. They are genuinely independent, which is why a service can be running yet absent after a reboot, or configured to boot yet not currently up. systemctl enable --now <unit> does both, and systemctl is-enabled <unit> tells you which state you are actually in."},{"question":"Why doesn't my unit file change take effect?","answer":"systemd caches unit definitions, so it keeps using the old one until you run sudo systemctl daemon-reload. After that, systemctl restart <unit> picks up the new configuration. If a change still seems ignored, check you edited the file systemd is actually reading, systemctl cat <unit> prints the effective definition including any drop-in overrides, which is the quickest way to spot that your edit is being overridden by something in /etc/systemd/system/<unit>.d/."},{"question":"How do I write a simple systemd service?","answer":"Create /etc/systemd/system/myapp.service with three sections: [Unit] for the description and ordering (After=network.target), [Service] for ExecStart, User, WorkingDirectory and Restart=on-failure, and [Install] with WantedBy=multi-user.target so enable knows where to link it. Then daemon-reload and enable --now. Use an absolute path in ExecStart, systemd does not consult your PATH, and remember the service runs as root unless you set User=."},{"question":"What does Type= mean in a systemd unit?","answer":"It tells systemd how to know the service has started. Type=simple assumes readiness the moment the process is forked, which suits anything that stays in the foreground. Type=forking is for daemons that background themselves, and needs PIDFile=. Type=notify waits for the process to signal readiness via sd_notify, which is the most accurate and what dependent units should rely on. Type=oneshot is for a task that runs and exits, often with RemainAfterExit=yes. A mismatch here is why dependencies start too early."},{"question":"How do I read logs for a single service?","answer":"journalctl -u myapp shows that unit's log, -f follows it live, and -n 50 limits it to the last 50 lines. --since "10 minutes ago" narrows by time and -p err by priority. Add -b for the current boot only, or -b -1 for the previous one, which is how you find out why the machine went down. By default the journal may be volatile and lost on reboot. Set Storage=persistent in /etc/systemd/journald.conf if you need history to survive."},{"question":"How do I override a unit file that came from a package?","answer":"sudo systemctl edit <unit> creates a drop-in at /etc/systemd/system/<unit>.d/override.conf containing only your changes, which a package upgrade will not touch. Editing the shipped file under /lib/systemd/system/ risks losing your work on the next update. One quirk worth knowing: to replace a directive that takes a list, such as ExecStart, you must first clear it with an empty assignment (ExecStart=) and then set the new value, or systemd appends rather than replaces."}]},{"slug":"linux-networking","title":"Linux Networking","seoTitle":"Linux Networking Commands: ip, ss, curl, dig and ping","description":"Diagnose Linux networking with ip and ss instead of ifconfig and netstat, learn why ping proves little, debug DNS with dig and choose rsync over scp.","content":"$39","difficulty":"Medium","duration":"20 min","keywords":["linux networking","ip addr route tutorial","curl wget ssh scp rsync","ss netstat nmap basics","etc hosts dns resolution","linux network troubleshooting","linux networking commands","ss -tlnp","ip addr vs ifconfig","netstat replacement linux","check open ports linux","ping works but connection refused","dig dns troubleshooting","scp vs rsync","ifconfig command not found","linux port not listening"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":10,"tableOfContents":[{"id":"why-networking-skills-matter","title":"Why Networking Skills Matter","level":2},{"id":"inspecting-interfaces-with-ip-addr","title":"Inspecting Interfaces with ip addr","level":2},{"id":"viewing-routes-with-ip-route","title":"Viewing Routes with ip route","level":2},{"id":"testing-reachability-with-ping","title":"Testing Reachability with ping","level":2},{"id":"fetching-data-with-curl-and-wget","title":"Fetching Data with curl and wget","level":2},{"id":"inspecting-listening-ports-with-ss-and-netstat","title":"Inspecting Listening Ports with ss and netstat","level":2},{"id":"basic-port-scanning-with-nmap","title":"Basic Port Scanning with nmap","level":2},{"id":"remote-access-with-ssh","title":"Remote Access with ssh","level":2},{"id":"file-transfer-with-scp-and-rsync","title":"File Transfer with scp and rsync","level":2},{"id":"etchosts-and-dns-resolution","title":"/etc/hosts and DNS Resolution","level":2},{"id":"a-practical-troubleshooting-flow","title":"A Practical Troubleshooting Flow","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-diagnosing-a-name-resolution-failure","title":"Exercise 1: Diagnosing a name-resolution failure","level":3},{"id":"exercise-2-inspecting-listening-services","title":"Exercise 2: Inspecting listening services","level":3},{"id":"exercise-3-efficient-repeated-file-syncs","title":"Exercise 3: Efficient repeated file syncs","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What replaced ifconfig and netstat on modern Linux?","answer":"The iproute2 suite. ip addr replaces ifconfig for viewing and configuring interfaces, ip route replaces route, ip neigh replaces arp, and ss replaces netstat. The old tools come from net-tools, which is unmaintained and not installed by default on many current distributions, including most container base images, which is why ifconfig: command not found is so common inside a container. ss is also significantly faster on a busy host, since it reads kernel socket data directly."},{"question":"How do I see which ports are open and listening?","answer":"sudo ss -tlnp, t for TCP, l for listening only, n for numeric ports rather than service names, p for the owning process. Add u for UDP. The sudo matters: without it you still see the ports but not which process owns them. Read the local address carefully, because 127.0.0.1:5432 means only that machine can connect while 0.0.0.0:5432 means anything that can route to the host can."},{"question":"Why can I ping a server but not connect to its service?","answer":"Because they test different layers. ping uses ICMP and confirms the host is reachable; a service needs a TCP port open, something listening on it, and no firewall in between. Work up the stack: ss -tlnp on the server to confirm something is listening and on which address, then curl -v telnet://host:port or nc -zv host port from the client to test the port, then check ufw status or the cloud security group. The most frequent cause is the service bound to 127.0.0.1 rather than 0.0.0.0."},{"question":"Why does ping fail when the server is clearly up?","answer":"ICMP is frequently blocked, by a firewall, a cloud security group, or as policy, and none of that affects normal traffic. AWS security groups, for instance, do not permit ICMP by default, so a perfectly healthy EC2 instance serving HTTPS will not answer a ping. Test the port you actually care about instead: nc -zv host 443 or curl -I https://host. A failed ping is weak evidence either way."},{"question":"How do I troubleshoot a DNS resolution problem?","answer":"dig +short example.com asks DNS directly and shows the answer, and dig @8.8.8.8 example.com compares against a public resolver to distinguish a broken local resolver from a genuine DNS problem. resolvectl status shows which servers systemd-resolved is actually using. Check /etc/hosts too. It takes precedence over DNS entirely, so a stale entry there overrides whatever DNS says and is easy to forget. Inside containers, check /etc/resolv.conf, which the runtime writes."},{"question":"What is the difference between scp and rsync?","answer":"scp copies files over SSH and copies everything, every time. rsync compares source and destination first and transfers only the differences, resumes interrupted transfers with --partial, can delete files that no longer exist at the source with --delete, and reports progress. For a one-off small file either is fine; for anything repeated or large, rsync -avz is substantially faster. OpenSSH has also deprecated the scp protocol on security grounds, which is another reason to standardise on rsync or sftp."}]},{"slug":"linux-disk-storage","title":"Linux Disk and Storage","seoTitle":"Linux Disk Usage: df vs du, Mounts, fstab and No Space Left","description":"Find and fix Linux disk problems: why df and du disagree, deleted-but-open files, inode exhaustion, persistent mounts by UUID in fstab and tar versus zip.","content":"$3a","difficulty":"Medium","duration":"18 min","keywords":["linux disk storage","df du lsblk tutorial","mount umount fstab","tar gzip zip unzip","find large files linux","linux disk usage","df vs du","no space left on device","df full du shows free","linux inodes full","etc/fstab uuid","tar gzip zip","lsof deleted files","du -sh sort"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":11,"tableOfContents":[{"id":"why-storage-skills-matter","title":"Why Storage Skills Matter","level":2},{"id":"checking-space-with-df","title":"Checking Space with df","level":2},{"id":"measuring-directory-usage-with-du","title":"Measuring Directory Usage with du","level":2},{"id":"viewing-block-devices-with-lsblk","title":"Viewing Block Devices with lsblk","level":2},{"id":"mounting-and-unmounting","title":"Mounting and Unmounting","level":2},{"id":"persistent-mounts-with-etcfstab","title":"Persistent Mounts with /etc/fstab","level":2},{"id":"creating-archives-with-tar","title":"Creating Archives with tar","level":2},{"id":"compressing-with-gzip-and-gunzip","title":"Compressing with gzip and gunzip","level":2},{"id":"working-with-zip-and-unzip","title":"Working with zip and unzip","level":2},{"id":"finding-large-files","title":"Finding Large Files","level":2},{"id":"real-world-scenario","title":"Real-World Scenario","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-checking-filesystem-capacity","title":"Exercise 1: Checking filesystem capacity","level":3},{"id":"exercise-2-configuring-persistent-mounts","title":"Exercise 2: Configuring persistent mounts","level":3},{"id":"exercise-3-building-a-compressed-backup","title":"Exercise 3: Building a compressed backup","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What is the difference between df and du?","answer":"df asks the filesystem how much space it has allocated, reported per mount point. du walks a directory tree and adds up the files it can see. They answer different questions and legitimately disagree: du misses files you lack permission to read, counts a hard-linked file once while df sees one copy of the data, and ignores space held by deleted-but-open files. Use df -h to find which filesystem is full, then du to find what is filling it."},{"question":"Why does df show a full disk when du shows plenty of free space?","answer":"Almost always a deleted file still held open by a running process. Unlinking a file removes the directory entry, but the blocks are not released until every file descriptor on it closes, so du cannot see it and df still counts it. This happens most often with a log file rotated or deleted while the service holds it open. Find the culprit with sudo lsof +L1, which lists open files with a link count of zero, then restart that process to release the space."},{"question":"How do I find what is using all my disk space?","answer":"Start at the top and work down: sudo du -sh / 2>/dev/null | sort -h shows which top-level directory is largest, then repeat inside the winner. du -sh | sort -h at each level narrows it quickly. ncdu does the same interactively and is worth installing. For individual large files, sudo find / -type f -size +500M -exec ls -lh {} \;. On servers the answer is usually /var/log or a container runtime directory such as /var/lib/docker."},{"question":"What are inodes and why does "no space left on device" appear with free space?","answer":"An inode holds a file's metadata, and a filesystem is created with a fixed number of them. Millions of tiny files can exhaust the inode table while gigabytes of space remain, and the kernel reports the generic No space left on device. df -i shows inode usage and confirms it in one command. The fix is deleting files rather than freeing bytes, typically a session directory, a mail spool or a cache that accumulated small files. Only reformatting changes the inode count."},{"question":"How do I make a mount persist across reboots?","answer":"Add a line to /etc/fstab with the device, mount point, filesystem type, options, dump and fsck fields. Use the filesystem UUID from blkid rather than /dev/sdb1, because device names depend on detection order and can change between boots. Pointing a mount at the wrong disk is a genuinely bad outcome. Then test with sudo mount -a, which applies fstab without rebooting. Skipping that test is how a typo becomes an unbootable machine, and adding nofail to the options limits the damage."},{"question":"What is the difference between tar, gzip and zip?","answer":"tar bundles many files into one archive and does not compress. gzip compresses a single file and does not bundle. They are used together, which is what tar -czf archive.tar.gz dir/ does. The z pipes the tar through gzip. zip does both at once and is the more portable choice for anything going to a Windows user. Practical notes: tar -tzf lists an archive's contents without extracting, which is worth doing before unpacking anything you did not create, and unzip -l is the equivalent."}]},{"slug":"linux-bash-scripting","title":"Linux Bash Scripting","seoTitle":"Bash Scripting Tutorial: set -euo pipefail, Quoting, trap","description":"Write bash scripts that fail loudly, not silently: use set -euo pipefail, quote variables, prefer [[ ]] over [ ], clean up with trap and lint with shellcheck.","content":"$3b","difficulty":"Hard","duration":"30 min","keywords":["bash scripting tutorial","linux shell scripting","bash variables loops functions","bash exit codes trap","stdin stdout stderr bash","devops bash scripts","bash scripting","set -euo pipefail","bash quoting variables","bash if [[ ]] vs [ ]","bash exit code","bash trap EXIT","shellcheck","bash shebang","bash script best practices","bash vs python scripting"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":12,"tableOfContents":[{"id":"why-bash-scripting-matters","title":"Why Bash Scripting Matters","level":2},{"id":"starting-with-the-shebang","title":"Starting with the Shebang","level":2},{"id":"variables-and-positional-parameters","title":"Variables and Positional Parameters","level":2},{"id":"conditionals-with-if-elif-and-else","title":"Conditionals with if, elif, and else","level":2},{"id":"loops-for-and-while","title":"Loops: for and while","level":2},{"id":"functions","title":"Functions","level":2},{"id":"arrays-and-string-operations","title":"Arrays and String Operations","level":2},{"id":"exit-codes","title":"Exit Codes","level":2},{"id":"standard-input-output-and-error","title":"Standard Input, Output, and Error","level":2},{"id":"cleaning-up-with-trap","title":"Cleaning Up with trap","level":2},{"id":"practical-example-argument-validation-script","title":"Practical Example: Argument Validation Script","level":2},{"id":"practical-example-service-health-check-script","title":"Practical Example: Service Health Check Script","level":2},{"id":"best-practices-for-bash-scripts","title":"Best Practices for Bash Scripts","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"exercise-1-counting-script-arguments","title":"Exercise 1: Counting script arguments","level":3},{"id":"exercise-2-writing-to-stderr","title":"Exercise 2: Writing to stderr","level":3},{"id":"exercise-3-registering-exit-cleanup","title":"Exercise 3: Registering exit cleanup","level":3},{"id":"key-takeaways","title":"Key takeaways","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What does set -euo pipefail do and why use it?","answer":"Four safety changes. -e exits the script as soon as any command fails, instead of blindly continuing. -u treats an unset variable as an error, catching typos and missing arguments rather than silently substituting an empty string. The difference between rm -rf "$DIR/" and rm -rf /. -o pipefail makes a pipeline fail if any command in it fails, not just the last. -x is the optional fourth, echoing each command as it runs, which is invaluable when debugging. Put it on line two of every script."},{"question":"What is the difference between [ ] and [[ ]] in bash?","answer":"[ is a command whose arguments happen to look like syntax, so an unquoted empty variable turns [ $x = "y" ] into [ = "y" ] and it fails with a syntax error. [[ ]] is bash syntax rather than a command: it handles empty variables safely, supports && and || inside, and adds pattern matching ([[ $f == .txt ]]) and regex (=~). Use [[ ]] in anything with a bash shebang; [ is only needed for strict POSIX sh scripts."},{"question":"Why do I need to quote variables in bash?","answer":"Because unquoted variables are word-split on whitespace and glob-expanded. rm $file with file="my document.txt" tries to delete two files, neither of which exists; rm "$file" deletes the right one. An empty unquoted variable disappears entirely, which can turn a command into something quite different from what you intended. The rule is simple enough to apply without thinking: always "$var", and always "$@" for arguments. shellcheck flags every violation."},{"question":"How do I check whether a command succeeded?","answer":"Every command sets $? to its exit code: 0 for success, non-zero for failure. Test it directly with if command; then, which reads better than comparing $?, or capture it immediately with rc=$? if you need the value, since the next command overwrites it. With set -e the script exits automatically on failure, and the idiom for "this one is allowed to fail" is command || true. In your own scripts, exit 1 on error so callers and CI can detect it."},{"question":"What is trap and when should I use it?","answer":"trap runs a command when the shell receives a signal or exits. The standard use is cleanup: trap 'rm -rf "$tmpdir"' EXIT deletes a temporary directory whether the script finishes normally, fails under set -e, or is interrupted with Ctrl-C. Without it, an early exit leaves temporary files, lock files and half-finished state behind. Trapping EXIT covers all those cases at once, which is why it is preferable to trapping individual signals."},{"question":"Should I write this in bash or move to Python?","answer":"Bash is excellent at running other programs and piping between them, if the script is mostly command invocations and a little control flow, it is the right tool. Move to Python once you need data structures, JSON or arithmetic beyond counting, error handling more nuanced than exit codes, or once the script passes a few hundred lines. The honest signal is associative arrays and nested quoting: by the time you are fighting bash's syntax rather than using it, the rewrite has already paid for itself."}]},{"slug":"linux-package-management","title":"Linux Package Management","seoTitle":"Linux Package Management: apt, dnf, yum and snap Compared","description":"Install software on any distro: apt versus apt-get, remove versus purge, fixing dpkg lock errors, dnf and rpm on Red Hat systems, and when snap is worth it.","content":"$3c","difficulty":"Easy","duration":"18 min","keywords":["linux package management","apt tutorial","dnf tutorial","yum commands","snap basics","appimage basics","apt vs apt-get","apt remove vs purge","unable to locate package apt","dpkg lock-frontend error","dnf vs yum vs rpm","apt autoremove","snap vs flatpak","apt-cache search","dpkg --configure -a"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":13,"tableOfContents":[{"id":"why-package-management-matters","title":"Why Package Management Matters","level":2},{"id":"apt-on-ubuntu-and-debian","title":"APT on Ubuntu and Debian","level":2},{"id":"refreshing-package-metadata","title":"Refreshing package metadata","level":3},{"id":"installing-packages","title":"Installing packages","level":3},{"id":"removing-packages-and-cleanup","title":"Removing packages and cleanup","level":3},{"id":"listing-package-information","title":"Listing package information","level":3},{"id":"dnf-and-yum-on-rhel-centos-and-fedora","title":"DNF and YUM on RHEL, CentOS, and Fedora","level":2},{"id":"installing-and-updating","title":"Installing and updating","level":3},{"id":"removing-and-listing","title":"Removing and listing","level":3},{"id":"snap-and-appimage-basics","title":"Snap and AppImage Basics","level":2},{"id":"snap","title":"Snap","level":3},{"id":"appimage","title":"AppImage","level":3},{"id":"holding-or-pinning-versions","title":"Holding or Pinning Versions","level":2},{"id":"holding-packages-with-apt","title":"Holding packages with APT","level":3},{"id":"controlling-versions-with-dnf","title":"Controlling versions with DNF","level":3},{"id":"a-practical-workflow","title":"A Practical Workflow","level":2},{"id":"what-you-should-remember","title":"What You Should Remember","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What is the difference between apt and apt-get?","answer":"apt is the newer command intended for interactive use: it has progress bars, colour, and combines the most common operations from apt-get and apt-cache in one place. apt-get has a stable, guaranteed-unchanging interface, which is why scripts and Dockerfiles should use it, apt prints a warning about unstable CLI behaviour when run non-interactively. Use apt at a terminal and apt-get in automation."},{"question":"What is the difference between apt remove, purge and autoremove?","answer":"remove uninstalls the package but leaves its configuration files in place, so reinstalling restores your settings. purge removes the configuration too, which is what you want when a broken config is the reason you are reinstalling. autoremove deletes packages that were pulled in as dependencies and are no longer needed by anything. Worth running occasionally, and worth reading the list first, because it occasionally proposes removing something you installed indirectly but do want."},{"question":"Why does apt install fail with "Unable to locate package"?","answer":"Usually a stale package index. apt-get update refreshes the metadata, and install then finds the package. This is exactly why update and install must share a single RUN in a Dockerfile, or the cached index goes stale. If it still fails after updating, the package is genuinely not in your configured repositories: check the spelling with apt-cache search <name>, and check whether it needs a PPA, a third-party repository or a different name on your distribution."},{"question":"How do I fix "could not get lock /var/lib/dpkg/lock-frontend"?","answer":"Another process holds the package manager lock, usually an automatic update running in the background, or a previous command that was interrupted. Wait a minute and retry, since unattended-upgrades finishes on its own. If nothing is running, sudo lsof /var/lib/dpkg/lock-frontend names the holder. Deleting the lock file is the advice you will find online and is a last resort: do it only after confirming no apt or dpkg process exists, then run sudo dpkg --configure -a to repair any half-finished state."},{"question":"What is the difference between dnf, yum and rpm?","answer":"rpm is the low-level package format and tool: it installs a single .rpm file and will not resolve dependencies for you. yum was the dependency-resolving package manager built on top of it, and dnf is its rewritten successor, on current RHEL, CentOS Stream and Fedora, yum is a symlink to dnf and the two are interchangeable. Use dnf for anything from a repository, and rpm -qa, rpm -ql and rpm -qf for querying what is installed and which package owns a file."},{"question":"Should I use snap, flatpak or the distribution's packages?","answer":"Distribution packages first: they are smaller, start faster, integrate with the system, and receive security updates through the channel you already monitor. Snap and Flatpak bundle their dependencies, which makes them useful for desktop applications that need newer libraries than your release ships, at the cost of size and slower first launch. On a server, prefer the distribution's packages or containers. Snaps auto-update on their own schedule, which is rarely what you want on infrastructure."}]},{"slug":"linux-environment-variables","title":"Linux Environment Variables","seoTitle":"Linux Environment Variables: export, PATH and .bashrc","description":"Learn Linux environment variables: shell versus exported variables, .bashrc versus .bash_profile, extending PATH safely and why sudo drops your environment.","content":"$3d","difficulty":"Medium","duration":"15 min","keywords":["linux environment variables","export command linux","PATH variable linux","printenv tutorial","linux profile files","env file sourcing","export variable bash","bashrc vs bash_profile","add directory to PATH permanently","sudo environment variables","printenv vs set","etc/environment","env vars secrets security","source bashrc","shell vs environment variable"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":14,"tableOfContents":[{"id":"what-environment-variables-are","title":"What Environment Variables Are","level":2},{"id":"shell-variables-vs-environment-variables","title":"Shell Variables vs Environment Variables","level":2},{"id":"scope-and-process-inheritance","title":"Scope and Process Inheritance","level":2},{"id":"persisting-variables-across-sessions","title":"Persisting Variables Across Sessions","level":2},{"id":"bashrc","title":"~/.bashrc","level":3},{"id":"bash_profile-and-profile","title":"~/.bash_profile and ~/.profile","level":3},{"id":"etcenvironment","title":"/etc/environment","level":3},{"id":"understanding-path","title":"Understanding PATH","level":2},{"id":"adding-a-directory-to-path","title":"Adding a directory to PATH","level":3},{"id":"env-files-and-sourcing","title":".env Files and Sourcing","level":2},{"id":"a-practical-example","title":"A Practical Example","level":2},{"id":"what-you-should-remember","title":"What You Should Remember","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"What is the difference between a shell variable and an environment variable?","answer":"A shell variable exists only in the current shell, NAME=value creates one, and a child process knows nothing about it. export NAME=value promotes it to an environment variable, which is copied into every process the shell starts afterwards. That distinction explains most "my script cannot see the variable" problems: the variable was set but never exported, so the script ran in a child process that never received it. printenv lists exported variables; set lists everything."},{"question":"Why does my variable disappear when I open a new terminal?","answer":"Because a variable set at the prompt lives only in that shell, and closing it discards everything. To persist one, add the export line to a startup file, ~/.bashrc for bash, ~/.zshrc for zsh, and either open a new shell or run source ~/.bashrc to apply it immediately. For values every user on the system should have, use /etc/environment or a file in /etc/profile.d/."},{"question":"What is the difference between .bashrc and .bash_profile?","answer":".bashprofile runs for login shells. An SSH session, or a console login. .bashrc runs for interactive non-login shells, which is what a new terminal tab on a desktop gives you. The practical consequence is that a variable set only in .bashrc is missing over SSH, and vice versa. The usual arrangement is to put everything in .bashrc and have .bashprofile source it, which most distributions already configure for you."},{"question":"How do I add a directory to PATH permanently?","answer":"Add export PATH="$PATH:/opt/tool/bin" to ~/.bashrc, then source ~/.bashrc. Two details matter. Include $PATH in the value. Omitting it replaces your entire PATH and breaks almost every command until you open a new shell. And order decides precedence: a directory placed before $PATH wins over the system version, which is how you make a Homebrew or pyenv binary take priority over one in /usr/bin."},{"question":"Why does sudo not see my environment variables?","answer":"Because sudo deliberately resets the environment for security. A user should not be able to influence a privileged command through PATH or LD_PRELOAD. Pass a value explicitly with sudo VAR=value command, preserve your environment with sudo -E command where policy allows, or use sudo -i for a full root login shell that reads root's own startup files. This is also why a script that works for you fails under sudo with "command not found"."},{"question":"Are environment variables a safe place for secrets?","answer":"They are better than a file committed to a repository and worse than a secrets manager. The problems are real: /proc/<pid>/environ exposes them to anyone who can read that process, they are inherited by every child process whether or not it should see them, they frequently end up in crash dumps and logs, and history captures the command that set them. For containers and Kubernetes they remain the normal interface, so the mitigation is to inject them at runtime from a secrets store rather than baking them into an image or a .env file in version control."}]},{"slug":"linux-cron-jobs","title":"Linux Cron Jobs","seoTitle":"Linux Cron Jobs: Crontab Syntax and Why a Job Isn't Running","description":"Schedule jobs with crontab: the five time fields, common examples, why a script that works manually fails in cron, capturing output, and systemd timers.","content":"$3e","difficulty":"Medium","duration":"18 min","keywords":["linux cron tutorial","crontab tutorial","cron job examples","cron expression syntax","etc cron d","systemd timers","cron jobs linux","crontab syntax","cron job not running","crontab -e","cron PATH environment","cron output log 2>&1","etc/cron.d user field","cron vs systemd timer","crontab every 5 minutes","cron day of week"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":15,"tableOfContents":[{"id":"what-cron-is","title":"What Cron Is","level":2},{"id":"managing-your-crontab","title":"Managing Your Crontab","level":2},{"id":"understanding-cron-syntax","title":"Understanding Cron Syntax","level":2},{"id":"common-cron-job-examples","title":"Common Cron Job Examples","level":2},{"id":"backup-script","title":"Backup script","level":3},{"id":"log-cleanup-or-rotation-helper","title":"Log cleanup or rotation helper","level":3},{"id":"health-check","title":"Health check","level":3},{"id":"system-cron-directories","title":"System Cron Directories","level":2},{"id":"etccrond","title":"/etc/cron.d/","level":3},{"id":"etccrondaily-etccronweekly-and-friends","title":"/etc/cron.daily/, /etc/cron.weekly/, and friends","level":3},{"id":"good-practices-for-cron-jobs","title":"Good Practices for Cron Jobs","level":2},{"id":"systemd-timers-as-a-modern-alternative","title":"systemd Timers as a Modern Alternative","level":2},{"id":"a-practical-troubleshooting-flow","title":"A Practical Troubleshooting Flow","level":2},{"id":"what-you-should-remember","title":"What You Should Remember","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"How do I read cron syntax?","answer":"Five fields: minute, hour, day of month, month, day of week. Then the command. 0 3 is 03:00 every day; /15 is every fifteen minutes; 0 9 1-5 is 09:00 on weekdays. The trap is that day-of-month and day-of-week are OR'd, not AND'd, so 0 0 1 1 runs on the 1st and every Monday. Use crontab -l to review and a site such as crontab.guru to check an expression before trusting it."},{"question":"Why does my cron job work manually but not from cron?","answer":"Almost always PATH. Cron runs with a minimal environment, typically just /usr/bin:/bin, so a command that resolves in your interactive shell is not found by cron, and your shell's profile is never sourced. Use absolute paths for everything (/usr/bin/python3 /opt/app/job.py), or set PATH= at the top of the crontab. The second most common cause is a relative path in the script itself, since cron starts in the user's home directory rather than where the script lives."},{"question":"How do I see cron job output and errors?","answer":"By default cron emails output to the account's local mailbox, which on most servers nobody reads. Redirect it explicitly instead: 0 3 * /opt/backup.sh >> /var/log/backup.log 2>&1. The 2>&1 is essential, without it you capture normal output and lose the error messages, which are exactly what you need. To confirm cron even ran, check journalctl -u cron on Debian and Ubuntu or journalctl -u crond on RHEL-family systems, or /var/log/syslog."},{"question":"What is the difference between crontab -e and /etc/crontab?","answer":"crontab -e edits the current user's personal crontab, stored under /var/spool/cron, and its entries run as that user with five time fields. /etc/crontab and files in /etc/cron.d/ are system-wide and take an extra field for the user to run as. Six fields before the command. Forgetting that extra field is the usual reason an /etc/cron.d entry silently does nothing. Prefer a file in /etc/cron.d/ for anything managed by configuration management, since it can be deployed as a file."},{"question":"Should I use cron or a systemd timer?","answer":"Cron for simple, portable, recurring jobs. It is universally available and a one-line entry. systemd timers for anything that needs more: journalctl integration for logs, Persistent=true to run a missed job after downtime, dependency ordering, resource limits, and randomised delays to avoid thundering herds. Timers need two files rather than one line, which is the main cost. In containers, neither may be present. Most base images run no cron daemon at all, so scheduling belongs outside the container."},{"question":"What does /5 mean in a cron expression?","answer":"A step value: "every 5" within that field. In the minute position, /5 runs at minute 0, 5, 10 and so on. In the hour position, 0 /6 runs at 00:00, 06:00, 12:00 and 18:00. Steps are not modulo arithmetic across boundaries, so /7 in the minute field fires at 0, 7, â¦, 56 and then again at 0. A 4-minute gap at the top of each hour. For intervals that do not divide 60, list the values explicitly."}]},{"slug":"linux-ssh-keys","title":"Linux SSH Keys","seoTitle":"SSH Keys on Linux: ssh-keygen, ssh-agent and ~/.ssh/config","description":"Set up SSH keys properly: generate Ed25519 keys with ssh-keygen, fix permission errors that block a valid key, use ssh-agent, ~/.ssh/config and ProxyJump.","content":"$3f","difficulty":"Medium","duration":"20 min","keywords":["ssh keys tutorial","ssh-keygen tutorial","authorized_keys","ssh config file","ssh agent","ssh copy id","ssh keys","ssh-keygen ed25519","permissions too open ssh key","ssh-copy-id","ssh-agent ssh-add","ssh agent forwarding security","ProxyJump bastion","ssh public vs private key","ssh passwordless login"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":16,"tableOfContents":[{"id":"why-ssh-keys-matter","title":"Why SSH Keys Matter","level":2},{"id":"how-ssh-key-authentication-works","title":"How SSH Key Authentication Works","level":2},{"id":"generating-a-key-with-ssh-keygen","title":"Generating a Key with ssh-keygen","level":2},{"id":"installing-the-public-key-on-a-server","title":"Installing the Public Key on a Server","level":2},{"id":"correct-file-permissions","title":"Correct File Permissions","level":2},{"id":"using-sshconfig","title":"Using ~/.ssh/config","level":2},{"id":"working-with-ssh-agent-and-ssh-add","title":"Working with ssh-agent and ssh-add","level":2},{"id":"agent-forwarding","title":"Agent Forwarding","level":2},{"id":"a-practical-workflow","title":"A Practical Workflow","level":2},{"id":"what-you-should-remember","title":"What You Should Remember","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"Should I generate an ed25519 or an RSA SSH key?","answer":"ed25519, unless you must talk to something ancient. ssh-keygen -t ed25519 -C "you@machine" produces a short, fast key with security comparable to a 3072-bit RSA key, and it is supported everywhere current. Choose RSA only for legacy systems that do not accept ed25519, and then use at least 4096 bits. Do not use DSA or ECDSA: DSA is disabled in modern OpenSSH, and ECDSA carries curve concerns ed25519 avoids."},{"question":"How do I fix "Permissions 0644 for id_ed25519 are too open"?","answer":"SSH refuses to use a private key that other accounts on the machine can read, and simply stops rather than risking it. chmod 600 ~/.ssh/ided25519 fixes the key, chmod 700 ~/.ssh the directory, and chmod 644 is correct for the .pub file, which is public by design. On the server side, ~/.ssh/authorizedkeys must be 600 and the user's home directory must not be group-writable, that last one is the cause of most "key is correct but login still fails" cases."},{"question":"What is the difference between the public and private key?","answer":"The private key stays on your machine and proves who you are; the public key is copied to every server you want to reach and can be shared freely. Authentication works by the server sending a challenge that only the matching private key can answer, so the private key never crosses the network, which is why it is safer than a password. ssh-copy-id user@host installs the public key into the server's authorized_keys. If you are ever asked to send a key, it is the .pub one."},{"question":"Should I put a passphrase on my SSH key?","answer":"Yes. Without one, anyone who obtains the file has your access to every server that trusts it, including from a stolen laptop or a backup. A passphrase encrypts the key at rest, and ssh-agent means you type it once per session rather than per connection: ssh-add ~/.ssh/id_ed25519, or on macOS ssh-add --apple-use-keychain to persist across reboots. Keys used by automation are the exception, and those should be separate, narrowly scoped keys rather than your personal one."},{"question":"What does ~/.ssh/config do and why use it?","answer":"It stores per-host settings so you stop retyping them. A block such as Host prod with HostName 10.0.4.12, User deploy, Port 2222 and IdentityFile ~/.ssh/prod_ed25519 turns a long command into ssh prod, and scp, rsync and Git all honour it. It is also where you configure jump hosts with ProxyJump bastion, which is far cleaner than chaining SSH commands, and ServerAliveInterval 60 to stop idle sessions dropping."},{"question":"Is SSH agent forwarding safe?","answer":"Not entirely, and it is worth knowing why. ssh -A lets processes on the remote host use your agent to authenticate onward, which means root on that host, or anyone who compromises it, can use your key while you are connected. They cannot steal the key itself, but they can act as you for the duration. Prefer ProxyJump (ssh -J bastion target), which tunnels the connection without exposing the agent. If you must forward, do it per-host in ~/.ssh/config, never globally."}]},{"slug":"linux-firewall","title":"Linux Firewall Basics","seoTitle":"Linux Firewall Basics: ufw, firewalld and iptables Compared","description":"Set up a Linux firewall without locking yourself out: compare ufw, firewalld and iptables, allow SSH first, default deny, zones and persistent rules.","content":"$40","difficulty":"Medium","duration":"20 min","keywords":["linux firewall tutorial","ufw tutorial","iptables tutorial","firewalld","firewall cmd","linux port security","linux firewall","ufw allow port","firewalld zones","iptables basics","ufw enable ssh lockout","port blocked after firewall allow","firewall-cmd --permanent","iptables persistent","default deny incoming","ufw status verbose"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":17,"tableOfContents":[{"id":"why-firewalls-matter","title":"Why Firewalls Matter","level":2},{"id":"ufw-on-ubuntu","title":"UFW on Ubuntu","level":2},{"id":"basic-ufw-workflow","title":"Basic UFW workflow","level":3},{"id":"iptables-basics","title":"iptables Basics","level":2},{"id":"firewalld-on-rhel-and-centos-style-systems","title":"firewalld on RHEL and CentOS Style Systems","level":2},{"id":"default-deny-and-least-privilege","title":"Default Deny and Least Privilege","level":2},{"id":"a-practical-example","title":"A Practical Example","level":2},{"id":"choosing-the-right-tool","title":"Choosing the Right Tool","level":2},{"id":"what-you-should-remember","title":"What You Should Remember","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"Should I use ufw, firewalld or iptables?","answer":"Use whichever your distribution manages, and use only one. ufw is the Ubuntu and Debian front end and is the simplest, ufw allow 22/tcp and you are done. firewalld is the RHEL, CentOS and Fedora equivalent, organised around zones. Both write rules through the kernel's packet filter for you, so running iptables commands alongside them produces a rule set that looks nothing like either tool reports. Work with iptables or nftables directly only when you genuinely need rules the front end cannot express."},{"question":"Why is my port still blocked after allowing it in the firewall?","answer":"Check three things in order, because the firewall is only one of them. First, is something actually listening, and on which address, sudo ss -tlnp, where 127.0.0.1:8080 means the service will never accept an external connection regardless of firewall rules. Second, is the rule active, ufw status verbose or firewall-cmd --list-all. Third, is there a firewall outside the host: a cloud security group, network ACL or load balancer rule, which is the most commonly forgotten layer on AWS, Azure and GCP."},{"question":"How do I allow SSH before enabling ufw?","answer":"sudo ufw allow 22/tcp (or sudo ufw allow OpenSSH) before sudo ufw enable, because ufw's default policy denies incoming traffic and enabling it first drops your current SSH session with no way back in on a remote machine. The command even warns you. If you have already locked yourself out, recovery means console access through your cloud provider or hypervisor. Change the port in the rule if SSH is not on 22."},{"question":"What does firewalld's zone concept mean?","answer":"A zone is a named set of rules applied to interfaces or source addresses, so the same host can treat traffic differently depending on where it arrives from, public for an internet-facing interface, internal or trusted for a private network. Rules are added per zone: firewall-cmd --zone=public --add-service=https. firewall-cmd --get-active-zones shows which interface is in which zone, and the most common surprise is adding a rule to the default zone while the interface you care about is in a different one."},{"question":"How do I make firewall rules survive a reboot?","answer":"ufw and firewalld both persist by design, with one catch for firewalld: changes are runtime-only unless you pass --permanent, so the pattern is firewall-cmd --permanent --add-service=https followed by firewall-cmd --reload. Raw iptables rules are not persistent and vanish on reboot, which is why iptables-persistent (or iptables-save into a file loaded at boot) exists. Verify by checking the rules after a reboot rather than assuming."},{"question":"What does "default deny" mean and why does it matter?","answer":"Blocking all incoming traffic by default and explicitly allowing only what is needed, rather than allowing everything and blocking known-bad ports. The difference is what happens to something you did not think about: with default deny, a service that starts listening unexpectedly, a debug port, a database bound to 0.0.0.0, a container publishing a port, is unreachable rather than exposed. ufw default deny incoming plus ufw default allow outgoing is the standard starting point."}]},{"slug":"linux-log-management","title":"Linux Log Management","seoTitle":"Linux Logs: journalctl, /var/log, tail -f and logrotate","description":"Find what went wrong in Linux logs: /var/log versus the systemd journal, tail -F over -f, grep filtering, logrotate, journald size caps and error triage.","content":"$41","difficulty":"Easy","duration":"15 min","keywords":["linux log management","journalctl tutorial","logrotate tutorial","tail f logs","var log structure","linux log monitoring","linux log files","journalctl","var/log","tail -f log file","logrotate configuration","journalctl vacuum size","syslog priority levels","journalctl -p err","linux logs filling disk","find errors in linux logs"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":18,"tableOfContents":[{"id":"why-logs-matter","title":"Why Logs Matter","level":2},{"id":"the-varlog-directory","title":"The /var/log Directory","level":2},{"id":"watching-logs-live-with-tail--f","title":"Watching Logs Live with tail -f","level":2},{"id":"filtering-logs-with-grep","title":"Filtering Logs with grep","level":2},{"id":"using-journalctl-for-systemd-logs","title":"Using journalctl for systemd Logs","level":2},{"id":"managing-log-growth-with-logrotate","title":"Managing Log Growth with logrotate","level":2},{"id":"a-practical-troubleshooting-flow","title":"A Practical Troubleshooting Flow","level":2},{"id":"what-you-should-remember","title":"What You Should Remember","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"Where are log files stored on Linux?","answer":"Under /var/log. The names vary by distribution: /var/log/syslog on Debian and Ubuntu holds general system messages, while RHEL-family systems use /var/log/messages. Authentication goes to /var/log/auth.log or /var/log/secure, and services keep their own directories such as /var/log/nginx/. On systemd distributions much of this is superseded by the journal, which is binary and read with journalctl rather than cat, so an empty-looking /var/log does not mean nothing is being logged."},{"question":"What is the difference between journalctl and reading /var/log?","answer":"journalctl reads systemd's structured binary journal, which lets you filter by unit, priority, boot and time, journalctl -u nginx -p err --since today is one command where grep across plain files would be several. Files under /var/log are plain text written by rsyslog or by applications directly, and are what non-systemd services and most containers produce. Both usually coexist: use journalctl for anything systemd manages and the files for everything else."},{"question":"How do I follow a log file in real time?","answer":"tail -f /var/log/syslog, or tail -F which survives the file being rotated out from under you. Worth preferring, since the plain -f silently follows a file nobody writes to any more after rotation. For systemd, journalctl -f, or journalctl -u myapp -f for one service. Combine with grep for a live filter: tail -F /var/log/nginx/access.log | grep " 500 "."},{"question":"How do I stop logs filling the disk?","answer":"logrotate handles files: a config in /etc/logrotate.d/ sets how often to rotate, how many to keep and whether to compress, and logrotate -d /etc/logrotate.d/myapp does a dry run so you can check it. For the journal, set SystemMaxUse=500M in /etc/systemd/journald.conf, or clear it now with journalctl --vacuum-size=200M. Note that rotating a file a process holds open does not free space until that process reopens it, which is what copytruncate or a postrotate reload signal is for."},{"question":"What do log priority levels mean?","answer":"Eight syslog severities, from 0 to 7: emerg, alert, crit, err, warning, notice, info, debug. journalctl -p err shows that level and everything more severe, which is the useful default when investigating. Most applications log at info in normal operation and can be turned up to debug temporarily. Worth remembering to turn it back down, since debug logging is a common cause of a disk filling overnight."},{"question":"How do I find errors across all logs quickly?","answer":"Start with journalctl -p err -b, which shows every error-level message from the current boot across all units, usually the fastest way to see what is broken. Then narrow to a unit with -u. For plain files, sudo grep -ri "error" /var/log --include=".log" | tail -50 casts a wide net, and adding -A 5 gives you the lines after each match, which is often where the actual cause is. Check timestamps against when the problem started rather than reading from the top."}]},{"slug":"linux-performance","title":"Linux Performance Monitoring and Troubleshooting","seoTitle":"Linux Performance Troubleshooting: CPU, Memory, Disk I/O","description":"Triage Linux performance in order: CPU, memory and I/O. Learn what load average counts, why free memory looks low and how to read iowait with vmstat.","content":"$42","difficulty":"Hard","duration":"25 min","keywords":["linux performance monitoring","vmstat tutorial","iostat linux","linux troubleshooting","load average linux","ss s network stats","linux performance troubleshooting","load average explained","free -h available memory","linux iowait high","iostat await util","top vs htop","find process high cpu linux","vmstat swap si so","sar sysstat history","linux memory pressure oom"],"publishedDate":"2026-07-14","updatedDate":"2026-09-16","order":19,"tableOfContents":[{"id":"why-performance-troubleshooting-needs-a-method","title":"Why Performance Troubleshooting Needs a Method","level":2},{"id":"cpu-analysis","title":"CPU Analysis","level":2},{"id":"top-and-htop","title":"top and htop","level":3},{"id":"load-averages-with-uptime","title":"Load averages with uptime","level":3},{"id":"cpu-details-with-lscpu","title":"CPU details with lscpu","level":3},{"id":"per-cpu-stats-with-mpstat","title":"Per-CPU stats with mpstat","level":3},{"id":"memory-analysis","title":"Memory Analysis","level":2},{"id":"free--h","title":"free -h","level":3},{"id":"vmstat","title":"vmstat","level":3},{"id":"procmeminfo","title":"/proc/meminfo","level":3},{"id":"disk-and-io-analysis","title":"Disk and I/O Analysis","level":2},{"id":"iostat","title":"iostat","level":3},{"id":"iotop","title":"iotop","level":3},{"id":"capacity-checks-with-df-and-du","title":"Capacity checks with df and du","level":3},{"id":"network-analysis","title":"Network Analysis","level":2},{"id":"socket-summaries-with-ss--s","title":"Socket summaries with ss -s","level":3},{"id":"interface-counters-from-procnetdev","title":"Interface counters from /proc/net/dev","level":3},{"id":"traffic-viewers","title":"Traffic viewers","level":3},{"id":"putting-it-together-during-an-incident","title":"Putting It Together During an Incident","level":2},{"id":"common-mistakes","title":"Common Mistakes","level":2},{"id":"what-you-should-remember","title":"What You Should Remember","level":2},{"id":"test-your-understanding","title":"Test Your Understanding","level":2},{"id":"frequently-asked-questions","title":"Frequently Asked Questions","level":2}],"noindex":false,"faqs":[{"question":"How do I tell whether a server is CPU, memory or I/O bound?","answer":"Work through four commands in order. uptime gives load averages. Compare them against your core count, not to each other. top or htop shows whether CPU time is user, system or wa (I/O wait); high wa with low user means the disk is the constraint. free -h shows memory, reading the available column rather than free. iostat -xz 2 shows per-device utilisation and await. High load with idle CPUs almost always means I/O or lock contention, not compute."},{"question":"What does load average actually measure?","answer":"The average number of processes either running or waiting to run over the last 1, 5 and 15 minutes, and on Linux, unlike some Unixes, it also counts processes blocked on disk I/O. It must be read relative to core count: 4.0 saturates a 4-core box and is light on 16. The three numbers matter as a trend, since a 1-minute figure far above the 15-minute one means the problem is arriving now. nproc gives your core count."},{"question":"Why does free -h show almost no free memory?","answer":"Because Linux uses otherwise idle memory as page cache, and that is the correct behaviour. Unused RAM is wasted RAM. The free column is genuinely unused memory and will always look small on a healthy server; the number to read is available, which accounts for cache the kernel can reclaim instantly. Real memory pressure shows up as swap activity in vmstat 1 (the si and so columns) or as OOM-killer messages in dmesg, not as a low free figure."},{"question":"How do I find what is using all the CPU or memory?","answer":"ps aux --sort=-%cpu | head and ps aux --sort=-%mem | head give an immediate ranked answer, which is often quicker than reading top. In htop, F6 sorts interactively. For a process you have identified, pidstat -p <pid> 1 shows its usage over time, and for memory specifically pmap -x <pid> or smem distinguishes shared from private memory. Worth doing before concluding a process is large, since ps counts shared libraries against every process using them."},{"question":"What is iowait and what do I do about it?","answer":"wa in top is the percentage of time CPUs sat idle with at least one outstanding disk request, so it means the CPU had nothing to do but wait. Confirm with iostat -xz 2: %util near 100 and a rising await identify the saturated device, and iotop -o names the processes responsible. The fixes are structural rather than tunable: faster storage, fewer synchronous writes, more caching, or moving the workload. Note that iowait can fall when CPU load rises, because the CPUs are then busy, so never read it alone."},{"question":"Which performance tools should I install before I need them?","answer":"htop for an interactive overview, iotop for per-process disk activity, sysstat for iostat, pidstat and sar, and ncdu for disk usage. sar is the one worth setting up in advance, because it records history, without it, a question like "what did memory do at 03:00 last night" has no answer. Installing these during an incident wastes the time when you least have it, so add them to your base image or configuration management."}]}],"category":"linux","errorPages":[{"slug":"linux-too-many-open-files","title":"Too many open files","description":"Fix "Too many open files": check the limit in /proc/PID/limits, find the leak with lsof, then raise LimitNOFILE in systemd. Covers Docker and Kubernetes."},{"slug":"linux-address-already-in-use","title":"bind: address already in use","description":"Fix "bind: address already in use": run ss -ltnp or lsof -i :PORT to find the listener, then stop it. For TIME_WAIT, set SO_REUSEADDR. Covers IPv6 overlap."},{"slug":"linux-no-space-left-on-device","title":"No space left on device but df shows free space","description":"Fix "No space left on device" with free space: run df -i for inodes and lsof +L1 for deleted open files. Covers wrong filesystems and finding the space with du."},{"slug":"linux-read-only-file-system","title":"Read-only file system","description":"Fix "Read-only file system": run mount | grep ' ro', check dmesg for I/O errors, then mount -o remount,rw. Covers fsck, containers and cloud volumes."}],"children":"$L43"}]
43:["$","div",null,{"className":"max-w-none","children":"$L44"}]
44:[["$","h2",null,{"className":"text-xl sm:text-2xl font-bold text-slate-900 mb-3 mt-8 first:mt-0 scroll-mt-24 border-l-4 border-teal-500 pl-3 sm:pl-4","id":"what-is-linux","children":"What Is Linux?"}],"\n",["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"Linux"}]," is an open source operating system family built around the ",["$","strong",null,{"children":"Linux kernel"}],". In simple terms, it is the software layer that helps your computer talk to hardware, manage files, run programs, and control memory, networking, and users."]}],"\n",["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"Many people say âLinuxâ when they really mean a complete operating system such as Ubuntu or CentOS. That is common in everyday conversation, but it helps to separate the main pieces."}],"\n",["$","h3",null,{"className":"text-lg sm:text-xl font-semibold text-slate-800 mb-2 mt-6 first:mt-0 scroll-mt-24","id":"kernel-vs-distribution-vs-shell","children":"Kernel vs Distribution vs Shell"}],"\n",["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["The ",["$","strong",null,{"children":"kernel"}]," is the core of the operating system. It handles low-level jobs such as CPU scheduling, memory allocation, device drivers, and ",["$","a",null,{"className":"text-teal-600 hover:text-teal-700 underline decoration-teal-300 hover:decoration-teal-500 transition-colors break-words","href":"/tutorials/linux/linux-process-management","children":"process management"}],"."]}],"\n",["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["A ",["$","strong",null,{"children":"distribution"}]," or ",["$","strong",null,{"children":"distro"}]," is a complete Linux operating system built around the kernel. It bundles package managers, default tools, system services, documentation, and a release model. Ubuntu, CentOS Stream, and Alpine are all distros."]}],"\n",["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["A ",["$","strong",null,{"children":"shell"}]," is the command-line interface you use to interact with the system. Popular shells include ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"bash"}],", ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"zsh"}],", and ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"sh"}],". When you type commands like ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"ls"}]," or ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"cd"}],", the shell reads your input and launches the right program."]}],"\n",["$","blockquote",null,{"className":"border-l-4 border-teal-500 bg-teal-50 pl-4 sm:pl-6 py-2 sm:py-3 my-4 italic text-slate-700 text-sm sm:text-base","children":["\n",["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"Tip:"}]," A useful mental model is: kernel = engine, distro = complete car, shell = steering wheel."]}],"\n"]}],"\n",["$","h2",null,{"className":"text-xl sm:text-2xl font-bold text-slate-900 mb-3 mt-8 first:mt-0 scroll-mt-24 border-l-4 border-teal-500 pl-3 sm:pl-4","id":"why-linux-is-everywhere-in-devops","children":"Why Linux Is Everywhere in DevOps"}],"\n","$L45","\n","$L46","\n","$L47","\n","$L48","\n","$L49","\n","$L4a","\n","$L4b","\n","$L4c","\n","$L4d","\n","$L4e","\n","$L4f","\n","$L50","\n","$L51","\n","$L52","\n","$L53","\n","$L54","\n","$L55","\n","$L56","\n","$L57","\n","$L58","\n","$L59","\n","$L5a","\n","$L5b","\n","$L5c","\n","$L5d","\n","$L5e","\n","$L5f","\n","$L60","\n","$L61","\n","$L62","\n","$L63","\n","$L64","\n","$L65","\n","$L66","\n","$L67","\n","$L68","\n","$L69","\n","$L6a","\n","$L6b","\n","$L6c","\n","$L6d","\n","$L6e","\n","$L6f","\n","$L70","\n","$L71","\n","$L72","\n","$L73","\n","$L74","\n","$L75","\n","$L76","\n","$L77","\n","$L78","\n","$L79","\n","$L7a","\n","$L7b","\n","$L7c","\n","$L7d","\n","$L7e","\n","$L7f","\n","$L80","\n","$L81","\n","$L82","\n","$L83"]
84:I[18308,["8500","static/chunks/8500-98e13bcce54aa7a0.js","3839","static/chunks/3839-ab8b319d7c7091ea.js","5899","static/chunks/5899-9fb98f224ca30c06.js","4913","static/chunks/app/tutorials/linux/%5Bslug%5D/page-99955cf7f6771b6f.js"],"default"]
45:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["Most modern infrastructure runs on Linux. Cloud ",["$","a",null,{"className":"text-teal-600 hover:text-teal-700 underline decoration-teal-300 hover:decoration-teal-500 transition-colors break-words","href":"/tutorials/docker/docker-vs-virtual-machines","children":"virtual machines"}],", ",["$","a",null,{"className":"text-teal-600 hover:text-teal-700 underline decoration-teal-300 hover:decoration-teal-500 transition-colors break-words","href":"/tutorials/kubernetes/introduction-to-kubernetes","children":"Kubernetes"}]," worker nodes, containers, CI runners, load balancers, and monitoring tools often use Linux under the hood."]}]
46:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","a",null,{"className":"text-teal-600 hover:text-teal-700 underline decoration-teal-300 hover:decoration-teal-500 transition-colors break-words","href":"/what-is-devops","children":"DevOps"}]," engineers use Linux because it is:"]}]
47:["$","ul",null,{"className":"space-y-2 mb-4 ml-4 sm:ml-6 list-disc marker:text-teal-500","children":["\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":[["$","strong",null,{"children":"Stable"}]," for long-running services"]}],"\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":[["$","strong",null,{"children":"Scriptable"}]," with shells and automation tools"]}],"\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":[["$","strong",null,{"children":"Transparent"}]," because system behavior is exposed through text files and logs"]}],"\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":[["$","strong",null,{"children":"Lightweight"}]," enough for servers and containers"]}],"\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":[["$","strong",null,{"children":"Widely supported"}]," by cloud and open source tooling"]}],"\n"]}]
48:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"If you know Linux, you can move more confidently between local development, staging, and production systems."}]
49:["$","h3",null,{"className":"text-lg sm:text-xl font-semibold text-slate-800 mb-2 mt-6 first:mt-0 scroll-mt-24","id":"a-real-example","children":"A Real Example"}]
4a:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["Imagine a team deploying a web application to ",["$","a",null,{"className":"text-teal-600 hover:text-teal-700 underline decoration-teal-300 hover:decoration-teal-500 transition-colors break-words","href":"/tutorials/aws/introduction-to-aws","children":"AWS"}],". Their ",["$","a",null,{"className":"text-teal-600 hover:text-teal-700 underline decoration-teal-300 hover:decoration-teal-500 transition-colors break-words","href":"/tutorials/aws/aws-ec2","children":"EC2 instances"}]," run Ubuntu, their ",["$","a",null,{"className":"text-teal-600 hover:text-teal-700 underline decoration-teal-300 hover:decoration-teal-500 transition-colors break-words","href":"/tutorials/docker/introduction-to-docker","children":"Docker"}]," containers use Alpine as a base image, and their Kubernetes control tools run on Linux in CI. Even if the developers use macOS or Windows locally, the production path still depends heavily on Linux skills."]}]
4b:["$","h2",null,{"className":"text-xl sm:text-2xl font-bold text-slate-900 mb-3 mt-8 first:mt-0 scroll-mt-24 border-l-4 border-teal-500 pl-3 sm:pl-4","id":"common-linux-distributions","children":"Common Linux Distributions"}]
4c:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"Different distros target different goals."}]
4d:["$","h3",null,{"className":"text-lg sm:text-xl font-semibold text-slate-800 mb-2 mt-6 first:mt-0 scroll-mt-24","id":"ubuntu","children":"Ubuntu"}]
4e:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"Ubuntu"}]," is one of the most beginner-friendly Linux distributions. It is common on cloud servers, tutorials, and developer workstations. It uses the ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"apt"}]," package manager and has a large community."]}]
4f:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"Example package install:"}]
50:["$","pre",null,{"className":"bg-slate-950 text-emerald-400 rounded-lg sm:rounded-xl p-3 sm:p-4 overflow-x-auto mb-4 border border-slate-700 shadow-lg text-xs sm:text-sm leading-relaxed [&_code]:bg-transparent [&_code]:p-0 [&_code]:text-inherit [&_code]:rounded-none","children":["$","code",null,{"className":"language-bash text-sm","children":"sudo apt update\nsudo apt install nginx\n"}]}]
51:["$","h3",null,{"className":"text-lg sm:text-xl font-semibold text-slate-800 mb-2 mt-6 first:mt-0 scroll-mt-24","id":"centos-stream","children":"CentOS Stream"}]
52:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"CentOS Stream"}]," is closely related to Red Hat Enterprise Linux. It is often seen in enterprise environments and is useful when learning Linux administration in business settings. Red Hat style systems typically use ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"dnf"}]," or ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"yum"}],"."]}]
53:["$","pre",null,{"className":"bg-slate-950 text-emerald-400 rounded-lg sm:rounded-xl p-3 sm:p-4 overflow-x-auto mb-4 border border-slate-700 shadow-lg text-xs sm:text-sm leading-relaxed [&_code]:bg-transparent [&_code]:p-0 [&_code]:text-inherit [&_code]:rounded-none","children":["$","code",null,{"className":"language-bash text-sm","children":"sudo dnf install nginx\n"}]}]
54:["$","h3",null,{"className":"text-lg sm:text-xl font-semibold text-slate-800 mb-2 mt-6 first:mt-0 scroll-mt-24","id":"alpine","children":"Alpine"}]
55:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"Alpine Linux"}]," is very small and security-focused. It is especially popular in containers because of its lightweight footprint."]}]
56:["$","pre",null,{"className":"bg-slate-950 text-emerald-400 rounded-lg sm:rounded-xl p-3 sm:p-4 overflow-x-auto mb-4 border border-slate-700 shadow-lg text-xs sm:text-sm leading-relaxed [&_code]:bg-transparent [&_code]:p-0 [&_code]:text-inherit [&_code]:rounded-none","children":["$","code",null,{"className":"language-bash text-sm","children":"apk add curl\n"}]}]
57:["$","blockquote",null,{"className":"border-l-4 border-teal-500 bg-teal-50 pl-4 sm:pl-6 py-2 sm:py-3 my-4 italic text-slate-700 text-sm sm:text-base","children":["\n",["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"Note:"}]," Alpine uses ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"musl"}]," instead of ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"glibc"}],", so a few binaries behave differently compared to Ubuntu or CentOS-based systems."]}],"\n"]}]
58:["$","h2",null,{"className":"text-xl sm:text-2xl font-bold text-slate-900 mb-3 mt-8 first:mt-0 scroll-mt-24 border-l-4 border-teal-500 pl-3 sm:pl-4","id":"linux-on-servers-vms-and-containers","children":"Linux on Servers, VMs, and Containers"}]
59:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"Linux is not just for laptops. You will meet it in several forms:"}]
5a:["$","ul",null,{"className":"space-y-2 mb-4 ml-4 sm:ml-6 list-disc marker:text-teal-500","children":["\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":[["$","strong",null,{"children":"Physical servers"}]," in data centers"]}],"\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":[["$","strong",null,{"children":"Virtual machines"}]," in cloud platforms"]}],"\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":[["$","strong",null,{"children":"Containers"}]," running one application process"]}],"\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":[["$","strong",null,{"children":"Embedded systems"}]," like routers and appliances"]}],"\n"]}]
5b:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"In containers, Linux becomes even more important because containers rely on Linux kernel features such as namespaces and cgroups."}]
5c:["$","h2",null,{"className":"text-xl sm:text-2xl font-bold text-slate-900 mb-3 mt-8 first:mt-0 scroll-mt-24 border-l-4 border-teal-500 pl-3 sm:pl-4","id":"gui-vs-command-line","children":"GUI vs Command Line"}]
5d:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"Linux can run desktop environments with graphical interfaces, but in DevOps you often work mainly in the terminal. That is because servers are commonly accessed over SSH and automated with scripts."}]
5e:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"A GUI is helpful for beginners, but command-line skills scale better when managing many systems."}]
5f:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"For example, updating ten servers through a GUI would be slow. Running one script over SSH is much faster."}]
60:["$","pre",null,{"className":"bg-slate-950 text-emerald-400 rounded-lg sm:rounded-xl p-3 sm:p-4 overflow-x-auto mb-4 border border-slate-700 shadow-lg text-xs sm:text-sm leading-relaxed [&_code]:bg-transparent [&_code]:p-0 [&_code]:text-inherit [&_code]:rounded-none","children":["$","code",null,{"className":"language-bash text-sm","children":"ssh devops@server1\nuname -a\ncat /etc/os-release\n"}]}]
61:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"These commands help you quickly learn what kernel and distro you are using."}]
62:["$","h2",null,{"className":"text-xl sm:text-2xl font-bold text-slate-900 mb-3 mt-8 first:mt-0 scroll-mt-24 border-l-4 border-teal-500 pl-3 sm:pl-4","id":"why-open-source-matters","children":"Why Open Source Matters"}]
63:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"Linux is open source, which means its source code can be inspected, modified, and redistributed under open source licenses. For DevOps teams, this matters because:"}]
64:["$","ul",null,{"className":"space-y-2 mb-4 ml-4 sm:ml-6 list-disc marker:text-teal-500","children":["\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":"bugs can be investigated more deeply"}],"\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":"tooling is highly customizable"}],"\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":"distributions can be optimized for different workloads"}],"\n",["$","li",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed pl-1","children":"vendor lock-in is reduced"}],"\n"]}]
65:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"Open source does not automatically mean easy, but it does mean the platform is flexible and widely shared."}]
66:["$","h2",null,{"className":"text-xl sm:text-2xl font-bold text-slate-900 mb-3 mt-8 first:mt-0 scroll-mt-24 border-l-4 border-teal-500 pl-3 sm:pl-4","id":"what-you-should-remember","children":"What You Should Remember"}]
67:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["Linux is the foundation of much of modern infrastructure. The ",["$","strong",null,{"children":"kernel"}]," is the core engine, a ",["$","strong",null,{"children":"distribution"}]," packages the full operating system, and the ",["$","strong",null,{"children":"shell"}]," gives you a command-line way to control it."]}]
68:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["As a ",["$","a",null,{"className":"text-teal-600 hover:text-teal-700 underline decoration-teal-300 hover:decoration-teal-500 transition-colors break-words","href":"/roadmaps/devops-engineer","children":"DevOps engineer"}],", Linux knowledge helps you troubleshoot servers, automate tasks, manage containers, and understand what production systems are actually doing."]}]
69:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"If you remember only one thing from this lesson, remember this: learning Linux is not just learning commands. It is learning how modern systems are operated."}]
6a:["$","h2",null,{"className":"text-xl sm:text-2xl font-bold text-slate-900 mb-3 mt-8 first:mt-0 scroll-mt-24 border-l-4 border-teal-500 pl-3 sm:pl-4","id":"test-your-understanding","children":"Test Your Understanding"}]
6b:["$","h3",null,{"className":"text-lg sm:text-xl font-semibold text-slate-800 mb-2 mt-6 first:mt-0 scroll-mt-24","id":"exercise-1-kernel-distribution-and-shell","children":"Exercise 1: Kernel, Distribution, and Shell"}]
6c:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"Scenario:"}]," A teammate says Ubuntu, Bash, and the Linux kernel are all the same thing."]}]
6d:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"Question:"}]," Which statement correctly separates those three concepts?"]}]
6e:["$","$L84",null,{"exercise":{"id":"introduction-to-linux-q1","title":"Exercise 1: Core Linux layers","description":"Identify the difference between the Linux kernel, a distribution, and a shell.","options":[{"id":"a","text":"The shell is the hardware layer, and the kernel is the command line."},{"id":"b","text":"The kernel manages core system functions, a distribution packages a complete OS, and a shell is the interface for running commands."},{"id":"c","text":"A distribution is only a package manager, while the kernel is a desktop environment."},{"id":"d","text":"The kernel, distribution, and shell are three names for the same component."}],"correctId":"b","explanation":"The lesson separates Linux into layers: the kernel handles low-level system work, a distro bundles the full operating system experience, and the shell is how you interact with it from the command line. Keeping those roles distinct makes Linux concepts much easier to understand.","wrongExplanations":{"a":"The shell is not a hardware layer. It reads your commands, while the kernel talks to hardware and manages processes and memory.","c":"A distribution is much more than a package manager, and the kernel is not a desktop environment. Distros bundle tools, defaults, services, and documentation around the kernel.","d":"They are related, but they are not interchangeable terms. The tutorial explicitly distinguishes the kernel, the distro, and the shell."}}}]
6f:["$","h3",null,{"className":"text-lg sm:text-xl font-semibold text-slate-800 mb-2 mt-6 first:mt-0 scroll-mt-24","id":"exercise-2-why-linux-shows-up-in-devops","children":"Exercise 2: Why Linux shows up in DevOps"}]
70:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"Scenario:"}]," Your company runs CI runners, Docker containers, and cloud VMs."]}]
71:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"Question:"}]," Why is Linux especially common in that kind of environment?"]}]
72:["$","$L84",null,{"exercise":{"id":"introduction-to-linux-q2","title":"Exercise 2: Linux in infrastructure","description":"Choose the reason Linux is widely used across servers, containers, and automation.","options":[{"id":"a","text":"Because Linux avoids logs and hides system behavior from operators."},{"id":"b","text":"Because Linux only works on developer laptops and not in production."},{"id":"c","text":"Because Linux is stable, scriptable, lightweight, and widely supported in modern infrastructure."},{"id":"d","text":"Because Linux removes the need for automation tools and shell scripts."}],"correctId":"c","explanation":"The tutorial highlights Linux as a strong fit for DevOps because it is stable for long-running services, transparent through text-based configs and logs, and easy to automate. Those traits make it a natural platform for cloud systems, containers, and CI pipelines.","wrongExplanations":{"a":"Linux does not avoid logs. In fact, one reason it is powerful in operations is that behavior is exposed through logs and text files.","b":"This is the opposite of the lesson. Linux is heavily used in production systems such as VMs, containers, and Kubernetes nodes.","d":"Linux encourages automation rather than replacing it. Shells, scripts, and automation tools are part of why it is so useful."}}}]
73:["$","h3",null,{"className":"text-lg sm:text-xl font-semibold text-slate-800 mb-2 mt-6 first:mt-0 scroll-mt-24","id":"exercise-3-choosing-a-distro-for-containers","children":"Exercise 3: Choosing a distro for containers"}]
74:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":[["$","strong",null,{"children":"Question:"}]," Which distribution from the lesson is especially popular as a lightweight container base image?"]}]
75:["$","$L84",null,{"exercise":{"id":"introduction-to-linux-q3","title":"Exercise 3: Container-friendly distro","description":"Pick the distribution the tutorial describes as small and common in containers.","options":[{"id":"a","text":"Alpine Linux"},{"id":"b","text":"CentOS Stream because it is the only distro that can run containers"},{"id":"c","text":"Ubuntu because it does not include a package manager"},{"id":"d","text":"A shell such as Bash, because shells are distributions"}],"correctId":"a","explanation":"The lesson calls out Alpine as small and security-focused, which is why it appears so often in container images. Its lightweight footprint makes it attractive when image size matters.","wrongExplanations":{"b":"CentOS Stream can be used in many contexts, but the tutorial specifically identified Alpine as the lightweight container favorite.","c":"Ubuntu does include a package manager, and the lesson did not describe it as the especially lightweight container base here.","d":"Bash is a shell, not a distribution. The tutorial clearly separates shells from distros."}}}]
76:["$","hr",null,{}]
77:["$","h2",null,{"className":"text-xl sm:text-2xl font-bold text-slate-900 mb-3 mt-8 first:mt-0 scroll-mt-24 border-l-4 border-teal-500 pl-3 sm:pl-4","id":"frequently-asked-questions","children":"Frequently Asked Questions"}]
78:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["$","strong",null,{"children":"What is the difference between the Linux kernel and a Linux distribution?"}]}]
79:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"The kernel is the core that manages memory, processes, devices and filesystems. Linux itself is only that kernel. A distribution wraps it with everything else you need to have a usable system: a package manager, an init system, shell utilities, libraries and defaults. Ubuntu, Alpine and Fedora all run the same kernel, so the differences between them are packaging, release cadence and choices such as glibc versus musl. That is why "Linux" in conversation almost always means a distribution."}]
7a:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["$","strong",null,{"children":"Which Linux distribution should I learn for DevOps?"}]}]
7b:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["Ubuntu, because it is the default on most cloud providers, has the largest body of documentation, and the ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"apt"}]," commands you learn transfer to Debian. Add familiarity with a RHEL-family system, Rocky, Alma or CentOS Stream, since regulated and enterprise environments use them and ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"dnf"}],", SELinux and ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"firewalld"}]," behave differently enough to matter. Alpine is worth knowing specifically because it dominates container base images, where musl instead of glibc causes real surprises."]}]
7c:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["$","strong",null,{"children":"Do I need to learn the command line, or is a GUI enough?"}]}]
7d:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"The command line, without much qualification. Servers are administered over SSH with no desktop installed, container images contain no GUI, and every automation tool, Ansible, CI pipelines, shell scripts, expresses work as commands. Beyond necessity it is also the only form that is reproducible: a command can be committed to a repository, reviewed and re-run, while a sequence of clicks cannot. A graphical environment is a convenience on your own machine and absent everywhere you will actually work."}]
7e:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["$","strong",null,{"children":"Why is Linux used for servers and containers rather than Windows?"}]}]
7f:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":"Three reasons compound. It is free to run at scale with no per-instance licensing. It is efficient. A minimal install uses a fraction of the memory a Windows Server needs, which directly changes cloud cost. And containers are a Linux kernel feature: namespaces and cgroups are what make them possible, which is why Docker on Windows and macOS runs a Linux virtual machine underneath. The ecosystem followed, so nearly all infrastructure tooling targets Linux first."}]
80:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["$","strong",null,{"children":"What is a shell and how does it differ from the terminal?"}]}]
81:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["The terminal is the window, the shell is the program running inside it that interprets what you type. ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"bash"}]," is the long-standing default, ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"zsh"}]," ships as standard on macOS, and ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"sh"}]," is the minimal POSIX shell that Alpine and most container images provide via ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"ash"}]," or ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"dash"}],". The distinction matters in practice: a script starting ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"#!/bin/bash"}]," fails on an image with no bash, and features such as ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"[[ ]]"}]," and arrays are bash extensions that plain ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"sh"}]," does not support."]}]
82:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["$","strong",null,{"children":"How much Linux do I need before learning Docker or Kubernetes?"}]}]
83:["$","p",null,{"className":"text-base sm:text-lg text-slate-700 leading-relaxed mb-4","children":["Enough to be comfortable rather than expert: navigating the filesystem, reading and editing files, permissions and ownership, processes and signals, and following logs. Those map directly onto container work. A container ",["$","em",null,{"children":"is"}]," a Linux process, ",["$","code",null,{"className":"bg-slate-100 text-rose-600 px-1 sm:px-1.5 py-0.5 rounded font-mono text-sm sm:text-base break-words","children":"docker exec"}]," drops you into a shell, and most failures are permissions, a missing file or a process not listening where you expected. People who skip this find container debugging opaque, because the concepts underneath were never learned."]}]
28:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
26:null
2a:[["$","title","0",{"children":"What Is Linux? Kernel, Distros and Shell for Beginners"}],["$","meta","1",{"name":"description","content":"Learn what Linux is: kernel versus distribution versus shell, which distro to learn for DevOps, and why servers and containers overwhelmingly run Linux."}],["$","link","2",{"rel":"author","href":"https://devopslesson.com"}],["$","meta","3",{"name":"author","content":"DevOpsLesson Team"}],["$","meta","4",{"name":"keywords","content":"linux tutorial, introduction to linux, linux for beginners, linux kernel vs distro, linux shell basics, devops linux fundamentals, what is linux, linux kernel vs distribution, best linux distro for devops, linux vs windows server, what is a shell linux, bash vs sh, alpine vs ubuntu, linux command line basics, learn linux for docker, linux tutorial, learn linux, linux for beginners, linux command line tutorial, linux permissions tutorial, bash scripting tutorial, linux file system tutorial, linux process management, linux networking commands, linux systemd tutorial, linux users groups tutorial, linux disk management, linux beginner guide 2026, linux terminal commands, linux for devops"}],["$","meta","5",{"name":"creator","content":"DevOpsLesson"}],["$","meta","6",{"name":"publisher","content":"DevOpsLesson"}],["$","meta","7",{"name":"robots","content":"index, follow"}],["$","meta","8",{"name":"googlebot","content":"index, follow, max-video-preview:-1, max-image-preview:large, max-snippet:-1"}],["$","link","9",{"rel":"canonical","href":"https://devopslesson.com/tutorials/linux/introduction-to-linux"}],["$","meta","10",{"name":"google-site-verification","content":"v1hGowZeYvsOScm3hhGtqYv7ZG_yiFG-YbjDK"}],["$","meta","11",{"property":"og:title","content":"Introduction to Linux"}],["$","meta","12",{"property":"og:description","content":"Learn what Linux is: kernel versus distribution versus shell, which distro to learn for DevOps, and why servers and containers overwhelmingly run Linux."}],["$","meta","13",{"property":"og:url","content":"https://devopslesson.com/tutorials/linux/introduction-to-linux"}],["$","meta","14",{"property":"og:site_name","content":"DevOpsLesson"}],["$","meta","15",{"property":"og:image","content":"https://devopslesson.com/api/og?title=Introduction+to+Linux&eyebrow=Linux+Basics+Tutorial"}],["$","meta","16",{"property":"og:image:width","content":"1200"}],["$","meta","17",{"property":"og:image:height","content":"630"}],["$","meta","18",{"property":"og:image:alt","content":"Introduction to Linux"}],["$","meta","19",{"property":"og:type","content":"article"}],["$","meta","20",{"property":"article:published_time","content":"2026-07-14"}],["$","meta","21",{"property":"article:modified_time","content":"2026-09-16"}],["$","meta","22",{"property":"article:author","content":"Vishvesh Patel"}],["$","meta","23",{"property":"article:tag","content":"linux tutorial"}],["$","meta","24",{"property":"article:tag","content":"introduction to linux"}],["$","meta","25",{"property":"article:tag","content":"linux for beginners"}],["$","meta","26",{"property":"article:tag","content":"linux kernel vs distro"}],["$","meta","27",{"property":"article:tag","content":"linux shell basics"}],["$","meta","28",{"property":"article:tag","content":"devops linux fundamentals"}],["$","meta","29",{"property":"article:tag","content":"what is linux"}],["$","meta","30",{"property":"article:tag","content":"linux kernel vs distribution"}],["$","meta","31",{"property":"article:tag","content":"best linux distro for devops"}],["$","meta","32",{"property":"article:tag","content":"linux vs windows server"}],["$","meta","33",{"property":"article:tag","content":"what is a shell linux"}],["$","meta","34",{"property":"article:tag","content":"bash vs sh"}],["$","meta","35",{"property":"article:tag","content":"alpine vs ubuntu"}],["$","meta","36",{"property":"article:tag","content":"linux command line basics"}],["$","meta","37",{"property":"article:tag","content":"learn linux for docker"}],"$L85","$L86","$L87","$L88","$L89","$L8a","$L8b","$L8c","$L8d"]
8e:I[86869,[],"IconMark"]
85:["$","meta","38",{"name":"twitter:card","content":"summary_large_image"}]
86:["$","meta","39",{"name":"twitter:title","content":"Introduction to Linux"}]
87:["$","meta","40",{"name":"twitter:description","content":"Learn what Linux is: kernel versus distribution versus shell, which distro to learn for DevOps, and why servers and containers overwhelmingly run Linux."}]
88:["$","meta","41",{"name":"twitter:image","content":"https://devopslesson.com/api/og?title=Introduction+to+Linux&eyebrow=Linux+Basics+Tutorial"}]
89:["$","link","42",{"rel":"shortcut icon","href":"/favicon.svg"}]
8a:["$","link","43",{"rel":"icon","href":"/icon","type":"image/png","sizes":"32x32"}]
8b:["$","link","44",{"rel":"icon","href":"/favicon.svg","type":"image/svg+xml"}]
8c:["$","link","45",{"rel":"apple-touch-icon","href":"/icon","sizes":"180x180","type":"image/png"}]
8d:["$","$L8e","46",{}
Learn what Linux is: kernel versus distribution versus shell, which distro to learn for DevOps, and why servers and containers overwhelmingly run Linux.
Learn the Linux directory tree: what /etc, /var and /usr hold, /tmp versus /var/tmp, virtual /proc and /sys, and the places where disks tend to fill up.
Move around Linux with confidence: absolute versus relative paths, reading ls -l output, which versus type, man pages and fixing command not found errors.