Master Linux from Scratch: From Basics to Advanced Skills

Última actualización: 12/03/2025
  • Linux underpins modern servers, cloud, security and development workflows, so learning it unlocks a wide range of technical career paths.
  • Mastering the shell, filesystem, text editing and Bash scripting gives you the core skills to automate tasks and manage systems efficiently.
  • Understanding users, permissions, networking, logging and process control is essential for secure, stable and maintainable Linux environments.
  • Monitoring, log analysis and tools like cron, SSH and sar enable you to operate, troubleshoot and scale real‑world Linux systems reliably.

Learn Linux

If you want a rock-solid career in tech, learning Linux is one of the smartest bets you can place on yourself. From cloud servers and DevOps pipelines to cybersecurity labs and supercomputers, Linux is quietly running the show behind the scenes. Mastering it doesn’t just make you faster and more efficient at everyday tasks – it also opens doors to roles in system administration, cloud engineering, security, SRE, and beyond.

This guide walks you from absolute basics to advanced Linux topics, keeping things hands‑on, practical and down‑to‑earth. You’ll start by understanding what Linux really is, how it’s built and distributed, and how to get it running on your own machine. From there, you’ll get comfortable with the command line, file system, text editing, shell scripting, package management, users and permissions, networking, log analysis, automation with cron, process control, troubleshooting, and more. Whether you’re switching from Windows/macOS or leveling up your existing skills, you’ll find plenty of material you can actually use on real systems.

Why Linux Matters and How It’s Built

Linux is a free, open‑source operating system inspired by Unix and first released by Linus Torvalds in 1991. Being open‑source means its source code is publicly available: anyone can read it, modify it, and redistribute their own versions. That collaborative model has turned Linux into the backbone of modern infrastructure: web servers, cloud platforms, IoT devices, Android phones, Chromebooks and much more rely on it every day.

When people say “Linux”, they often mix up three related but distinct ideas: the kernel, the operating system and the distribution. The kernel is the core program that manages hardware resources like memory, CPU time, disks and devices, and provides system calls for applications. On top of that, you have system utilities, libraries, shells and tools that together form a complete operating system. A distribution (or “distro”) bundles the Linux kernel with all that user‑space software, a package manager and installer, plus defaults and policies chosen by a community or vendor.

Because the kernel is open‑source, anyone can take it, add tools and configs, and publish their own distro. That’s why you’ll see so many flavors: some tiny and single‑purpose, others full‑featured with thousands of packages. Many are “derived” from others – for example, Ubuntu and Kali are built on top of Debian and reuse its package system, repos and a big part of its toolchain. Derivative distros gain stability, security updates and massive software repositories from their parent, while focusing their own effort on special features, defaults or use cases.

Popular beginner‑friendly and advanced distributions each target different audiences and workflows. Ubuntu is one of the most widely used and is very friendly for newcomers, with strong community support. Linux Mint is also beginner‑oriented and adds codecs and multimedia support out of the box. Arch Linux is minimal and hands‑on, aimed at experienced users who want full control and a DIY approach. Manjaro builds on Arch but adds graphical tools and sane defaults. Kali Linux focuses on penetration testing and comes with a huge arsenal of security and hacking tools preinstalled.

Setting Up Linux on Your Machine

The best way to really learn Linux is to use it daily, so step one is getting access to a Linux environment you can experiment with safely. You can install Linux as your main OS, run it alongside Windows, spin it up in a virtual machine, use the Windows Subsystem for Linux, or even work entirely in browser‑based terminals or cloud instances, depending on your needs and hardware.

Installing Linux as your primary operating system gives you the purest, fastest experience. A common beginner path is to install Ubuntu LTS (Long Term Support) on bare metal. You download the official ISO, create a bootable USB drive (tools like Rufus on Windows make this trivial), boot from it, and walk through the installer. LTS releases give you several years of security and maintenance updates, so you don’t need to reinstall often. Once installed, you just reboot, log in with the user/password you set and you’re ready to customize your desktop and install apps.

There are a few advanced install options worth exploring once you’re comfortable. Disk partitioning lets you slice your drive into separate partitions for root, home, and maybe a dedicated data or backup partition. Swap configuration can enable hibernation or give low‑RAM systems some breathing room. These topics are not mandatory on day one, but they matter a lot on production servers or carefully tuned workstations.

If you want to keep Windows but still use Linux regularly, you have several good options. Dual‑booting lets you install Linux alongside Windows and choose which OS to start at boot; each has its own partition, but only one runs at a time. Virtual machines using tools like VirtualBox or VMware let you run Linux as a guest OS inside Windows, assigning CPU cores, RAM, disk and network resources to the VM. Browser‑based terminals and cloud VPS instances (AWS EC2, Azure, DigitalOcean and others) give you remote Linux shells you can access from anywhere, usually over SSH.

On Windows 10 and 11, the Windows Subsystem for Linux (WSL2) is a fantastic way to get a full Linux user space integrated into your Windows desktop. You enable the “Windows Subsystem for Linux” feature, open an elevated terminal and run wsl --install. By default, that installs Ubuntu. After a reboot, you’ll be asked to create a Linux username and password, and then you can launch Ubuntu from the Start menu and use it like a regular Linux shell – no heavy VM images required.

Regardless of how you install Linux, you’ll spend a lot of time in the terminal, so learn how to open it quickly. On Ubuntu desktops, you can search for “Terminal”, pin it to the dock, or use the keyboard shortcut Ctrl+Alt+T. Many file managers let you open a terminal directly in the current folder via a right‑click menu option like “Open in Terminal”, which is super handy when you’re working on project directories.

Getting Comfortable with the Shell and Bash Basics

Linux’s power really shines through the command line, and the program that gives you that interface is called a shell. Over time, different shells have appeared (sh, ksh, csh, zsh, etc.), but on most modern Linux distributions the default is Bash – the GNU Bourne Again SHell. To check what you’re actually using, run echo $SHELL; if you see something like /bin/bash, you’re in Bash.

The terminal emulator is the window you type into; the shell is the program running inside it that interprets your commands. People often use the words interchangeably, but it helps to separate them mentally: if you open the GNOME Terminal or Konsole, that’s the terminal; Bash (or another shell) runs inside it and shows the prompt where you type commands. On a server without a graphical interface, you might be connected via SSH directly into a shell.

The shell prompt usually shows your user, host and current directory, then a character indicating your privilege level. A typical non‑root prompt might look like [alice@server ~]$, and a root prompt like [root@server ~]#. The $ means a regular user, while # warns you that you’re operating as root and potentially able to break the system with a single bad command.

Most Linux commands follow a predictable structure: a command name, optional flags, and optional arguments. A generic pattern looks like command [options] [arguments]. For example, ls -a /var/log uses the ls command with the -a option (show hidden files) and /var/log as an argument (the directory to list). Some commands work fine with no options or arguments at all; for others, you must specify both or they’ll fail.

Your best friend for exploring commands is the built‑in manual system. Most utilities ship with a man page: run man ls, man grep, etc., and you’ll get detailed docs covering usage, options and examples. It’s a great habit to skim the man page for each new tool you pick up, at least once.

Bash also supports a bunch of keyboard shortcuts and conveniences that speed up your workflow massively. Press the up arrow to scroll through previous commands, Ctrl+A to jump to the beginning of the current line, Ctrl+K to delete from the cursor to the end of the line, and Tab for auto‑completion of commands and file paths. The history command prints your recent commands, which you can reuse or search through.

You can always check which user you’re currently acting as with the tiny but useful whoami command. Just type whoami and press Enter; the shell prints your effective username. This is especially important when you’ve been switching between users (e.g., via su or sudo) and want to be sure you’re not about to run something dangerous as root by mistake.

Understanding the Linux System and Hardware Info

Before you start tweaking a machine, it helps to know what OS, kernel and CPU you’re working with. The uname command prints kernel and system information; uname -a shows the kernel name, hostname, kernel version, build time, architecture and more. It’s a quick way to confirm whether you’re on 64‑bit Linux, which kernel version is running, and what platform you’re on.

For deeper insights into the processor itself, use lscpu. It summarizes CPU architecture, supported modes (32‑bit, 64‑bit), endianness, number of cores, threads per core, sockets, and min/max clock speeds. This information is vital when you’re sizing workloads, tuning performance or making sure software you install is built for the right architecture (for example, x86_64 vs ARM).

Working with the Linux Filesystem

Linux filesystems are arranged like an upside‑down tree with a single root directory / at the top. Every file and directory lives somewhere under this root, and the slash character / is used as a path separator. A full (absolute) path such as /home/alice/projects starts from the root and walks down the tree, while a relative path like projects/demo is interpreted relative to your current working directory.

Different top‑level directories have specific, standardized purposes, which you’ll quickly memorize with use. For example, /bin holds essential user commands, /sbin holds essential system binaries, /boot contains boot loader files, /etc stores system‑wide configuration, /home provides personal directories for each user, /root is the root user’s home directory, /lib and /usr/lib host shared libraries, /var holds variable data like logs and queues, and /tmp is a scratch area for temporary files.

To see where you are in the directory tree at any time, use pwd (print working directory). If you’ve been jumping around, a quick pwd tells you the absolute path of your current directory. To move around, use cd: cd /etc goes to /etc, cd .. jumps up one level, cd ../.. goes up two, cd or cd ~ returns to your home directory, and cd - toggles back to the previous directory.

Managing files and folders from the command line boils down to a handful of core tools. Create directories with mkdir, optionally using -p to create nested paths in one go (for example, mkdir -p tools/index/helper-scripts). Create empty files with touch file.txt, or multiple files at once with touch file1.txt file2.txt file3.txt. Remove files with rm, delete directories recursively with rm -r, and remove empty directories with rmdir. The -f flag on rm forces deletion without prompting, so handle it with care, especially outside of your home directory.

Copying, moving and renaming are handled by cp and mv. To copy a file into another directory, use cp source.txt /path/to/dest/. To duplicate a file under a new name in the same directory, use cp old.txt new.txt. Moving works similarly: mv file1.txt backup/ moves it to backup, while mv oldname.txt newname.txt simply renames it. The same commands work for directories as long as you include the right flags when needed.

Linux also gives you powerful searching capabilities via the find command. The basic pattern is find /path -type X -name "pattern", where -type f looks for regular files, -type d for directories, -type l for symbolic links, and -type b/c for block and character devices. You can match specific names or wildcards (e.g., "*.log" for log files), include hidden files with patterns starting with a dot, search by size with -size (like +250M for files larger than 250 MB), or by modification time with -mtime (for example, -mtime -10 to find files changed in the last 10 days).

When you want to inspect file contents, there’s a small toolkit of commands you’ll use constantly. cat prints an entire file at once, which is fine for small files. less and more let you scroll through large files page by page, search within them, and quit with q. head shows the first lines of a file, tail shows the last lines, and tail -f follows a file in real time – an essential trick for watching logs. wc counts lines, words and bytes, while diff compares two files line by line and shows how they differ, either in unified form or side‑by‑side.

Text Editing with Vim and Nano

On servers and many headless systems, you edit configuration and code entirely from the terminal, so learning at least one console text editor well is a must. Two editors you’ll find almost everywhere are Vim and Nano. Both allow you to edit text files, but their philosophies are different: Vim is modal and keyboard‑centric, designed for heavy power users; Nano is simpler and more discoverable for beginners.

Vim is incredibly powerful once you get past its learning curve. It has multiple modes: normal (or command) mode for navigation and editing commands, insert mode for typing text, and visual modes for selecting characters, lines or blocks. You start in normal mode; press i, I, a, A, o or O to enter insert mode in different ways, and use Esc to return to normal mode. Navigation can be done with arrow keys or with the classic h, j, k, l; 0 jumps to the start of a line, $ to the end, gg to the top of the file and G to the bottom.

Vim’s editing shortcuts let you move and manipulate text at high speed once they’re in your muscle memory. You can delete a character with x, delete a whole line with dd, copy (yank) with yy or visual selection + y, and paste below the cursor with p or above with P. Searching is done with /pattern going forward or ?pattern backward; n jumps to the next match and N to the previous one. A common global search‑and‑replace pattern is :%s/old/new/g to replace all occurrences of old with new in the file.

Exiting Vim is all about commands that start with a colon. Hit Esc to ensure you’re in normal mode, then type :w to save, :q to quit (failing if you have unsaved changes), :wq (or :x) to save and quit, or :q! to quit and discard changes. You can also split the window (:split and :vsplit) and move between panes with Ctrl+w followed by h, j, k or l.

Nano, by contrast, focuses on being straightforward and beginner‑friendly. To open or create a file, run nano filename. You move the cursor with arrow keys, type to insert text, and use the shortcuts listed at the bottom of the screen – they’re usually in the form ^O for Ctrl+O, ^X for Ctrl+X, and so on. Ctrl+O saves, Ctrl+X exits (prompting you to save if needed), Ctrl+K cuts a line, Ctrl+U pastes, and Ctrl+W searches for text. Options like -l will show line numbers, and Alt+G lets you jump directly to a given line.

Getting into Bash Scripting

Once you’re comfortable running commands manually, the next big leap is putting sequences of commands into scripts so they can be reused and automated. A Bash script is just a text file containing commands that Bash executes line by line. By saving tasks like cleanup routines, backups or deployment steps into scripts, you reduce mistakes and save a ton of time.

By convention, Bash scripts often have a .sh extension, but that’s not technically required. What matters much more is the shebang line at the top of the file: something like #!/bin/bash or #!/usr/bin/env bash. That first line tells the system which interpreter to use when you run the script. You can find the path to Bash with which bash, and use that in the shebang if you want to be explicit.

A minimal example script might ask for a directory and list its contents. You could create run_all.sh with content like: a shebang, an echo that prints today’s date (for example, using backticks or $(date)), a prompt asking the user for a path, a read command to store that input into a variable, and finally an ls command that uses that variable to list files. Comments start with # and are ignored by the interpreter, so you can document each step for yourself and others.

To run scripts directly, you need to make them executable and then invoke them. Use chmod u+x script.sh to give the owner execute permission, then either call it via the shell (bash script.sh) or run it as ./script.sh from the directory where it lives. If the script is on your $PATH, you can call it from anywhere by name.

Bash variables are dynamically typed containers you can assign text or numbers to and reuse later. You assign with name=value (no spaces), and reference with $name. For example, country=Netherlands followed by echo $country prints the value. You can also set a variable based on the value of another: same_country=$country copies the existing content. Naming conventions say your variable should start with a letter or underscore, consist only of letters, digits and underscores, and avoid reserved keywords like if, then or fi.

There are several ways to feed input into a script and send output elsewhere. Inside scripts, read var waits for the user to type something and stores it into var. You can iterate through lines of a file with a while read line; do ...; done < filename loop. Command‑line arguments show up as $1, $2, etc., so a script that echoes $1 can greet a name passed on the command line. For output, you use echo as usual, but you can redirect it with > to overwrite a file, >> to append, or combine with other commands using pipes.

Conditional logic and loops let your scripts make decisions and repeat work. The basic if syntax in Bash uses brackets like if [ condition ]; then ... elif [ condition ]; then ... else ... fi. You can test numeric comparisons (-gt, -lt, etc.), string comparisons, file existence and more, and you can combine conditions with logical AND (-a) and OR (-o). Loops come in while forms that continue while a condition is true, and for loops that iterate over lists like for i in {1..5}; do echo $i; done. case statements let you match an expression against a set of patterns in a clean, switch‑like syntax.

Managing Software with Package Managers

Unlike Windows, where you often download installers from random websites, Linux distributions generally manage software via centralized repositories and package managers. A package is just a bundle of files containing the program’s binaries, libraries, metadata and install scripts. Packages come either as source code (needing compilation) or as architecture‑specific binaries (e.g., x86_64), and they often depend on other packages being installed.

On Debian‑based systems like Ubuntu, the apt family of tools is the standard way to handle packages. The package manager keeps an index of available software in configured repositories, which you refresh with sudo apt update. To install a package, you use sudo apt install htop or similar; any required dependencies are automatically pulled in from the repos. To upgrade already installed packages, run sudo apt upgrade. To remove a package you no longer need, use sudo apt remove packagename. Low‑level package operations and logs are handled by dpkg, whose logs you can inspect at /var/log/dpkg.log.

Sometimes you’ll download standalone .deb files from vendor websites rather than from your distro’s repos. In that case, you can install them with sudo dpkg -i package_name.deb from the directory where the file lives. If dependencies are missing, you can usually fix them with sudo apt -f install. To list all packages installed via dpkg, use dpkg --list. Graphical frontends like Synaptic give you a GUI on top of the same underlying package system if you prefer clicking to typing for some tasks.

Users, Groups, Permissions and Security

Linux is a multi‑user system by design, so understanding users, groups and permissions is central to keeping a machine secure. Every account is identified by a username (human‑friendly) and a numeric User ID (UID, system‑friendly). Similarly, groups have names and numeric Group IDs (GIDs). Special accounts exist for services and daemons, and there’s a single all‑powerful superuser account called root with UID 0.

Information about users is stored primarily in /etc/passwd, and passwords are kept (hashed) in /etc/shadow. A typical line in /etc/passwd looks like root:x:0:0:root:/root:/bin/bash, which breaks down into: username, password placeholder, UID, primary GID, descriptive info, home directory and login shell. Group info lives in /etc/group, where entries list the group name, password placeholder, GID and member usernames.

Each user belongs to one primary group and optionally many supplementary groups. The primary group is usually created alongside the user and shares its name; files the user creates are normally owned by this group. Supplementary groups add extra permissions – for example, being added to the sudo group on Ubuntu lets you run commands with elevated privileges. You can check your IDs and group memberships with the id command, and list processes associated with a user via ps -u username.

File permissions in Linux are represented in the classic rwx triplets for user, group and others. Running ls -l shows lines like -rw-rw-r-- or drwxrwx---, where the first character indicates file type (- for regular file, d for directory), and the next nine characters are three sets of r (read), w (write) and x (execute). The first triplet applies to the file’s owner, the second to the group, and the third to everyone else. For directories, “execute” controls the ability to enter the directory and access contents; for files, it controls whether the file can be run as a program or script.

You can change permissions using the chmod command in either symbolic or numeric form. Symbolic mode uses letters for classes (u, g, o) and +, -, = to add, remove or set permissions, e.g. chmod u+x script.sh to add execute permission for the owner. Numeric (octal) mode represents permissions as sums of 4 (read), 2 (write) and 1 (execute), giving three digits for user, group and others; chmod 751 file sets rwxr-x--x. Both styles are worth being comfortable with.

Ownership changes are handled with chown, which can modify the user, the group or both. chown newuser filename changes the owner, chown newuser:newgroup filename adjusts both owner and group, and chown :groupname dir just changes the group. The -R option applies ownership changes recursively to all files and directories inside a given directory, which is useful for preparing application trees or shared folders.

Switching identities is done with su and sudo, and you should know when to use which. su otheruser starts a shell as otheruser after you enter that user’s password; su - opens a full login shell, updating environment variables. sudo is safer for day‑to‑day admin tasks: it lets approved users run individual commands with elevated privileges while logging everything in /var/log/auth.log. If a user isn’t allowed to use sudo, attempts will be logged and rejected.

User management at the command line uses tools like useradd, usermod, userdel and passwd. sudo useradd username creates a new account (though you’ll often prefer higher‑level wrappers that also create home directories and set shells by default). usermod lets you change usernames, home directories, shells, group memberships and more. userdel removes accounts, with -r also deleting their home directories. passwd sets or changes passwords – run it as root with a username to set someone else’s password, or without arguments to change your own.

Connecting Remotely with SSH

Secure Shell (SSH) is the standard way to log into remote Linux systems securely over the network. It uses encryption, public‑key cryptography and strong authentication to protect your traffic. The default port is 22, though many admins change it to reduce noise from automated scans. On the client side, the core tool is simply ssh.

To connect to a remote server, you need the server’s IP or hostname, a username and usually a password or key. The command format is ssh username@server_ip, for example ssh john@192.168.1.10. The first time you connect, SSH will ask you to verify the server’s host key fingerprint; after that, you’ll be prompted for the user’s password (unless you’re using key‑based auth). Once logged in, you’re at a shell prompt on the remote machine and can run commands as if you were sitting at its console.

If the SSH service is listening on a non‑standard port, specify it with the -p option. For instance, if your server uses port 2222 for SSH, you’d connect with ssh -p 2222 username@server_ip. You can also configure host aliases and default ports in ~/.ssh/config to avoid typing the full details every time.

Analyzing Logs and Text Data

On a live system, logs are your black box recorder: they tell you what happened, when, and often why. Application logs, system logs, security logs and network logs can all grow into thousands or millions of lines, so you need efficient ways to search, filter and summarize them. Fortunately, the Unix toolbox has several complementary text‑processing tools that shine here.

grep is your go‑to for finding lines matching a pattern in files or streams. The basic usage is grep "search_string" filename, but options make it much more flexible: -r searches recursively through directories, -i ignores case, -n shows line numbers, -c counts matching lines, -v inverts the match (show non‑matching lines), and -w restricts matches to whole words. grep -l lists only filenames that contain a match, which is handy when you’re scanning many files at once.

sed (the stream editor) processes text line by line, applying commands like substitution, deletion and printing. A classic substitution example is sed 's/old-text/new-text/' file, which replaces the first occurrence of old-text on each line with new-text. Adding a g flag makes it global per line. With -n '/pattern/p', you can print only lines matching a pattern, and with '/pattern/d' you can drop matching lines from the output. Regular expressions let you surgically extract or transform parts of log lines like dates, IDs or status codes.

awk is a small language for working with structured text, especially column‑based data like logs. Its basic form is awk 'pattern { action }' file, where each input line is automatically split into fields $1, $2, etc., using whitespace as the default separator (configurable with -F). You might use awk '{ print $1, $2 }' logfile to print dates and times, or awk '/ERROR/ { print $0 }' to show only error lines. More advanced patterns let you build frequency tables, compute aggregates and summarize metrics on the fly.

cut, sort and uniq slot into this toolbox to extract and aggregate specific bits of information. cut pulls out specific fields given a delimiter and field numbers, such as cut -d ' ' -f 3 logfile to get the third column. sort orders lines alphabetically or numerically, with -n for numeric sort, -r for reverse order and -k to choose a sort key. uniq collapses consecutive duplicate lines, and with -c it counts them. Piping them together – for example, cut -d ' ' -f 3 logfile | sort | uniq -c – is a classic pattern to produce counts of log levels or error codes.

Processes, Jobs and Signals

Every command you run on Linux is a process, and knowing how to inspect, prioritize and kill processes is crucial for system administration. Each process gets a numeric Process ID (PID) and a Parent Process ID (PPID), and most processes ultimately trace their ancestry back to systemd or another init system with PID 1. Processes consume CPU, memory and other resources, and they transition through states like running, sleeping, stopped and zombie.

The ps command gives you snapshots of what’s running; the common ps aux form is especially handy. It shows the user, PID, CPU and memory usage, virtual and resident memory sizes, controlling terminal, state, start time, CPU time and the command used to start the process. The STAT column encodes the state: R for running, S and I for sleeping, D for uninterruptible sleep (usually I/O), T for stopped and Z for zombie processes awaiting reaping by their parent.

Shell “jobs” are processes you started from the current shell, which you can move between foreground and background. Appending & to a command, like sleep 300 &, starts it in the background immediately. The jobs command lists them with job numbers like [1], [2], etc. You can bring a job to the foreground with fg %1, suspend it with Ctrl+Z, and resume it in the background with bg %1. This is particularly useful when running long tasks while you continue using the same terminal for other commands.

To terminate or control processes directly, you use signals via commands like kill, killall and pkill. kill PID sends SIGTERM by default, politely asking the process to exit. kill -9 PID sends SIGKILL, which forcefully kills it without cleanup. Other common signals include SIGHUP (often used to reload configs), SIGINT (akin to Ctrl+C), SIGSTOP (pause) and SIGCONT (resume). killall processname and pkill pattern let you target all processes by name or regex pattern, respectively.

Input, Output, Redirection and Pipelines

Every process starts with three standard streams: standard input (stdin), standard output (stdout) and standard error (stderr). In Linux, these correspond to file descriptors 0, 1 and 2. By default, stdin is your keyboard, and stdout and stderr go to your terminal, but you can redirect them to files or other processes using simple operators.

Redirection lets you capture output or error messages into files or mix them together. Using > overwrites a file with stdout (e.g., ls > files.txt), while >> appends instead of overwriting. You can redirect stderr separately with 2> error.txt. To send both stdout and stderr to the same file, you can do command > all_output.txt 2>&1, which means “send stdout to all_output.txt and then send stderr wherever stdout is currently going”.

Pipelines connect commands so that the output of one becomes the input of the next. The pipe operator | is the glue: ls | grep image lists files and then filters for those containing image in their names. This composability is a core Unix philosophy: instead of one giant tool, you string together many small tools to solve complex problems.

Scheduling and Automation with Cron

For repetitive tasks – backups, cleanups, reports, health checks – cron is the built‑in job scheduler that keeps things running on autopilot. A background daemon (crond or equivalent) reads per‑user and system crontab files and executes specified commands at scheduled times. Each user can define their own crontab, and access can be controlled via /etc/cron.allow and /etc/cron.d/cron.deny on many systems.

You edit your crontab with crontab -e and list current entries with crontab -l. Each line in a crontab has five timing fields (minute, hour, day of month, month, day of week) followed by the command to execute. Asterisks act as wildcards, ranges and lists are allowed, and step values like */5 mean “every 5 units”. For example, 0 22 * * 1-5 runs at 22:00 Monday through Friday, and */1 * * * * runs every minute.

As a simple example, you might schedule a script that logs the date and time once per minute to a file. The script could be date-script.sh containing a shebang and echo $(date) >> /path/to/date-out.txt. After making it executable, you’d add a cron entry like */1 * * * * /bin/sh /home/username/date-script.sh. Over time, date-out.txt fills up with timestamped lines, letting you verify that cron is firing on schedule.

Troubleshooting cron usually involves verifying schedules, checking logs and capturing output. First, double‑check the timing fields using a helper site like crontab.guru if needed. Then inspect system logs (for example, /var/log/syslog on Ubuntu) for entries mentioning CRON and your command. You can also redirect a cron job’s stdout and stderr to a log file with syntax like * * * * * sh /path/to/script.sh &> /path/to/log_file.log to catch errors that would otherwise vanish.

Networking Essentials on Linux

Linux offers a rich set of networking tools to inspect interfaces, connections, routing and connectivity. Traditional utilities like ifconfig and netstat are still widely used, though modern replacements like the ip suite and ss exist as well. You’ll use these when you’re figuring out IP addresses, testing reachability or debugging weird network behavior.

ifconfig (or ip addr) lists network interfaces and their configuration. You’ll see entries for physical interfaces (like eth0 or wlp3s0), loopback (lo) and possibly virtual bridges. Fields include IPv4 and IPv6 addresses, netmasks, broadcast addresses, MAC addresses and statistics on packets sent/received and errors.

netstat reports active connections, listening sockets, routing tables and per‑protocol statistics. Options like -a show all sockets, -l shows listening ports only, -t shows TCP connections, -u shows UDP, -r prints the kernel routing table, and -p adds the PID/program name to each connection listing, which is very handy when figuring out which process is bound to which port.

Simple reachability testing is often done with ping, which sends ICMP echo requests to a host. ping google.com will show round‑trip times and packet loss until you stop it with Ctrl+C. The summary at the end tells you how many packets were transmitted and received, and what percentage were lost, helping you spot flaky connections or DNS problems.

curl is another essential tool, this time for interacting with HTTP(S) and other protocols over URLs. By default, curl URL issues a GET request and prints the response body. With -o, you can save the result to a file; with -I, you request only the headers, which is great for checking response codes and server metadata. It’s particularly handy for quickly testing HTTP APIs or remote endpoints from the command line.

Monitoring and Troubleshooting Linux Systems

Serious Linux work always involves monitoring and troubleshooting: finding bottlenecks before they explode, and diagnosing issues quickly when they do. You’ll draw on many of the tools already mentioned, plus some specialized ones, to assess CPU load, memory pressure, disk usage, process behavior and network health.

uptime gives you a quick snapshot of how long the system has been running and what the load averages look like. The three numbers at the end represent average run queue lengths over the past 1, 5 and 15 minutes. If you divide those by the number of CPUs (which you can see via lscpu), you get an idea of how busy each core is. Consistently high load averages relative to CPU count usually indicate CPU saturation or blocked processes waiting on I/O.

Memory and disk usage are easily checked with free and df. free -mh reports total, used and available memory and swap, with human‑readable units. It’s normal for Linux to use a lot of memory for cache and buffers, so focus on the “available” value and swap usage. df -h shows disk space and utilization for each mounted filesystem; as a rule of thumb, keeping usage under ~80% avoids some performance and fragmentation issues.

Process‑level insight in real time is where top and related tools shine. Running top displays a dynamic, updating view of CPU, memory and process stats. You can sort by different columns, search for processes, and even kill a process by pressing k and typing its PID. More advanced variants like htop offer color, mouse support and easier navigation, but the core concepts are the same.

Network health often comes down to ports, connections and packet loss. Tools like netstat (or ss) show which ports are in LISTEN, ESTABLISHED, TIME_WAIT and other TCP states, letting you spot port exhaustion or runaway connection growth. ping helps detect packet loss and latency spikes. For deeper packet‑level inspection, tcpdump can capture traffic to .pcap files for later analysis in Wireshark.

For historical performance data, the sar command (from the sysstat package) is incredibly useful. Once sysstat is installed and enabled, the system periodically logs CPU, memory, network and disk statistics to files in /var/log/sysstat. You can query these logs later with sar -u for CPU usage, sar -r for memory, sar -S for swap, sar -d for block devices or sar -n DEV for network interfaces, specifying intervals and counts or pointing directly at daily archives such as sa04 for a specific day of the month.

Finally, always remember that logs are your narrative of what the system was doing around the time of a problem. Before restarting services or rebooting servers, copy or snapshot relevant logs so you don’t lose crucial context. Combined with metrics from tools like sar, top and free, they’ll help you reconstruct root causes, improve reliability and avoid repeat incidents. Over time, this feedback loop is what transforms you from “I can follow a tutorial” to “I can run production systems with confidence.”

Related posts: