Linux Novice.
Level 1 User
No signup required. Progress is saved locally. Export your save code to play on another device.
Earned Badges
Learn Linux by actually using it.
Real terminal commands, real filesystem simulation β no videos, no fluff.
Interactive Learning Path.
Follow the path of command quests. Click any unlocked challenge node to open your interactive Linux shell workspace.
1. Filesystem Basics
Who Am I and Where Am I?
Imagine walking into a massive, dark library with millions of books, but you have no map, and you can't even remember your own name tag. Before you can look up anything, you need to know who you are and where you are standing. In the Linux shell, we start with the exact same questions! - The `whoami` command prints the username you are currently logged in as. - The `pwd` (print working directory) command acts like a GPS, showing you the exact folder path where you are currently standing.
Navigating & Listing Files
Now that you know where you are, how do you look around and move to a different room in this digital library? In Linux, we do this using two simple commands: - `ls`: It's like turning on the lights in a room to see all the files and folders sitting inside it. - `cd <path>`: Short for "change directory", this lets you walk through a door into another folder. To specify where you want to go, you can use **absolute** paths (starting from the very root `/` of the system, like `/var/log`) or **relative** paths (based on where you are right now, like using `..` to step back out into the parent folder).
Creating Directories
Imagine your desk is piled high with loose papers, and you need physical folders to keep things tidy. In Linux, we organize files by creating folders (directories) using the `mkdir` (make directory) command. Running `mkdir code` creates a brand-new folder named "code" right where you are. You can create folders anywhere in the filesystem by giving `mkdir` a relative or absolute path.
Nested Directories & Options
Imagine trying to build a set of nesting dolls, but you have to build the outermost ones before you can build the tiny one inside. By default, `mkdir` is like thatβit refuses to create a folder deep inside folders that don't exist yet. To skip the hassle of creating folders one-by-one, we use a switch: - The `-p` (or `--parents`) option tells `mkdir` to automatically build any missing parent folders on its way to the final folder. For example, `mkdir -p workspace/src/utils` creates `workspace`, `workspace/src`, and `workspace/src/utils` all in a single command. **Why this matters**: If you run `mkdir workspace/src/utils` without `-p`, and `workspace` and `workspace/src` don't already exist, you'll get: `mkdir: cannot create directory 'workspace/src/utils': No such file or directory`. The `-p` flag fixes this by creating all missing parent folders automatically.
Clearing the Screen
Ever get overwhelmed when your desk is covered in messy notes and papers? Your terminal can get just as cluttered. When it does, you can sweep all the old text away and start fresh. - The `clear` command wipes the visible screen clean, sliding previous output out of view so you have a fresh, blank canvas at the top of the terminal.
Finding Shell Help
When you buy a new board game, you usually peek at the rulebook or reference card to see what moves are allowed. In our terminal emulator, you have a built-in cheat sheet! - The `help` command lists every single command this simulator supports, along with details about whether it supports piping or redirecting outputs.
2. File Manipulation
Creating Empty Files
Imagine wanting to start writing a new journal entry, but first you need a blank piece of paper. In Linux, we grab a fresh, empty text file using the `touch` command. - The `touch` command creates a brand new, empty file if it doesn't exist yet (like running `touch draft.txt` to create `draft.txt`). If the file already exists, it simply updates the file's "last modified" timestamp without changing its contents. Let's put a file in our new projects folder.
Reading File Contents
Think of opening a folder, pulling out a page of text, and holding it up to read. In Linux, we read files instantly without opening a heavy text editor using the `cat` (concatenate) command. - The `cat` command prints the entire contents of a file directly onto your terminal screen. For instance, running `cat notes.txt` lets you see what is written inside `notes.txt` right away.
Peeking at Files (head & tail)
Now that you can read a whole file with `cat`, what if the file has thousands of lines and you only want to see the top or bottom? Dumping a huge file with `cat` floods your screen. Instead, we use `head` and `tail` to peek at the edges. - The `head` command displays the first 10 lines of a file by default. You can change this using `-n <number>` (e.g. `head -n 5 log.txt` for the first 5 lines). - The `tail` command displays the last 10 lines by default, supporting the same `-n` option. - Crucially, `tail -f` (follow) monitors a file in real-time, showing new lines as they are written by the system. This is a sysadmin's favorite tool for watching live logs.
Interactive File Scrolling (less & more)
Peeking at the top and bottom of a file with `head` and `tail` is great, but what if you need to browse a long configuration file page-by-page? That's what pagers like `less` and `more` are for. - Pagers load files interactively, showing one page of text at a time to prevent system slowdowns on large files. - `less` is the modern choice, allowing you to scroll both forward and backward using the arrow keys, search text with `/`, and exit by pressing `q`. - `more` is an older, simpler pager that only scrolls forward.
Handling Spaces in File Names
If you tell a robot to "paint my bedroom blue", it needs to know whether "my bedroom" is a single place or if "my" and "bedroom" are two different instructions. Linux uses spaces to separate commands from their arguments. So if you run `mkdir my folder`, Linux thinks you want to create two separate folders: one named "my" and another named "folder"! - To tell Linux that a name with spaces is a single item, we must wrap it in quotes (`"my folder"` or `'my folder'`) or use a backslash to escape the space (`my\ folder`).
Writing & Overwriting Files
If you want to write a message on a chalkboard, you first wipe the board completely clean and then write your new words. In Linux, we write messages to files using the `>` (output redirection) operator. - The `echo "message"` command normally prints text to the screen. - By adding the `>` symbol, we redirect that text into a file instead. E.g., `echo "Hi" > greeting.txt` writes "Hi" into `greeting.txt`. If the file already has text, `>` completely overwrites it with the new message.
Appending to Files
Instead of cleaning the chalkboard, what if you just want to add a new line at the bottom? In Linux, we add text to the end of a file without touching the existing content using the `>>` (append redirection) operator. - The `>>` operator appends your new text to the very bottom of the file. E.g., `echo "New Line" >> logs.txt` adds "New Line" to the end of `logs.txt` while keeping all your old logs safe.
Copying & Moving Files
Imagine reorganizing your room: sometimes you want to make a photocopy of a document to keep in another drawer, and other times you just want to grab a folder and slide it into a new shelf or change its label. We do this in Linux with simple commands: - `cp <source> <destination>` creates an identical duplicate of a file in a new location. - `mv <source> <destination>` moves a file to a new folder, or renames the file if you keep it in the same folder (e.g., `mv old.txt new.txt`).
Wildcards & Multi-File Operations
Imagine you have a stack of folders labeled "log_monday", "log_tuesday", and "log_wednesday", and you want to open and read all of them at once without typing every name out. Linux lets you use **wildcards** as search shortcuts! - The `*` symbol matches any characters of any length. E.g., `cat log_*` reads every file that starts with "log_". - The `?` symbol acts as a single-character placeholder. E.g., `log_?.txt` matches `log_1.txt` but will ignore `log_12.txt`.
Removing Files & Folders
When you clean up your physical desk, you might throw old papers into a recycling bin where you can retrieve them if you made a mistake. In Linux, there is no safety netβwhen you delete something from the terminal, it is gone forever! - The `rm` command deletes files. - Because folders can contain other files, `rm` won't delete a folder by default. You must add the `-r` (recursive) flag to tell Linux to dive in and delete the folder along with everything inside it. **Why this matters**: If you run `rm downloads` without `-r` when `downloads` is a folder, you'll get: `rm: cannot remove 'downloads': Is a directory`. The `-r` flag tells Linux to recursively delete the folder and everything inside it.
3. Pipes & Filtering
Introduction to Pipes & wc
Imagine an assembly line where one worker wraps a product and immediately hands it to the next worker to pack it into a boxβno intermediate storage needed. In Linux, we connect commands exactly like this using a **pipe** (`|`). - A pipe (`|`) routes the output of one command directly into the input of the next command. For example, `ls | wc -l` lists files and immediately hands that list to `wc -l` (word count - lines), which counts them up on the fly without needing temporary files. **Why this matters**: If you run `wc` without `-l`, it outputs three separate numbers: lines, words, and bytes (e.g., ` 5 10 85`). This makes it difficult to use in pipelines or scripts that need a clean, single-number count. The `-l` flag limits the output to just the line count.
Sorting and Finding Uniques
Imagine sorting a deck of cards where duplicates are scattered all over. To easily spot and remove duplicates, you'd first group the identical cards together. In Linux, the `uniq` command filters out repeating lines, but it has a catch: it **only detects duplicates that are right next to each other**! - To remove all duplicates from a messy list, you must first sort the lines using `sort` and then pass the result to `uniq`. E.g., `sort raw.txt | uniq` organizes and cleans the list in one go.
Filtering with grep
Imagine looking through a massive, thousand-page logbook to find every time a system error occurred. Doing this manually would take hours! In Linux, we use `grep` as our digital magnifying glass to search for specific words or patterns instantly. - The `grep` command filters files or piped text, printing only the lines that match your search word. For example, running `grep "ERROR" logs.txt` scans the file and extracts only the lines containing "ERROR".
4. Redirection & Security
Changing File Permissions
Imagine running a business where only managers can sign checks, employees can read schedules, and visitors can only look at the store sign. In Linux, we control who can read, write, or run files using a security system of numbers (called octal representation): - `7` = Full access: Read + Write + Execute (`rwx`) - `6` = Modify access: Read + Write (`rw-`) - `5` = Read and run access: Read + Execute (`r-x`) - `4` = Read-only access: Read (`r--`) We apply these settings with `chmod <octal> <file>`. E.g., `chmod 755 script.sh` lets you run the script, while others can only read and run it. We have a script named `deploy.sh` that's currently locked downβlet's make it executable!
Hidden Files & Configurations
Think of a secret drawer under your desk where you keep system settings so they don't clutter up your main workspace. In Linux, we create hidden files simply by starting their names with a dot (`.`). - These dotfiles (like `.bashrc` or `.config`) store user preferences and config settings behind the scenes. - A standard `ls` command won't show them. To peek at these hidden files, you must add the `-a` (all) flag, running `ls -a`. **Why this matters**: If you run `ls` without `-a`, hidden files (whose names start with a `.`) are completely omitted from the output. You won't see important files like `.config_names` and might think they are missing. The `-a` flag tells `ls` to list all files, including hidden ones.
Changing File Ownership
Imagine buying a house and having to officially register the deed under a new owner's name. In Linux, every file and folder has an official owner and a group. If you need to hand a file's ownership over to someone else (like the system administrator), you use the `chown` (change owner) command. - Because changing who owns a file is a sensitive security action, you must prefix it with `sudo` to run it with administrative privileges. E.g., `sudo chown root reports.csv` assigns the file to the user "root".
5. Superuser & Packages
Superuser Privileges (sudo)
Imagine working on your computer with a standard account to prevent accidentally deleting critical operating system files. When you need to install software or modify system settings, your computer asks for admin authorization. In Linux, we use `sudo` (short for "superuser do") as our administrative key card. - The `root` user is the master administrator account with full control over the system. - Standard users are blocked from reading sensitive files (like the password database `/etc/shadow`). By typing `sudo` before a command, you run it with temporary administrator powers to bypass these blocks.
Package Management (apt)
Think of installing apps on your smartphone using the App Store or Google Play Store. It is safe, curated, and automated. In Linux, we use a command-line app store called a package manager to fetch and install software securely. - On Ubuntu/Debian systems, the standard package manager is `apt` (Advanced Packaging Tool). - Installing software changes system-wide folders, so you always need to authorize it using `sudo`. E.g., `sudo apt install tree` downloads and installs the directory visualizer "tree".
6. Disk & System Resources
Checking Disk Space (df)
Imagine trying to download a huge video game and getting a "storage full" error, but you aren't sure which disk drive is the bottleneck. In Linux, we check our system's storage capacity using the `df` (disk free) command. - The `df` command displays the total, used, and available space on all your connected drives. - By running `df -h` (adding the `-h` flag for "human-readable"), you see storage in friendly gigabytes (G) and megabytes (M) instead of confusing block counts, making it easy to spot which drive (like `/` or `/home`) is full. **Why this matters**: If you run `df` without `-h`, the sizes are displayed in raw 1K-block numbers (e.g., `49258284` instead of `47G`), which is extremely hard for a human to read and calculate. The `-h` flag formats these sizes into human-friendly gigabytes (G) and megabytes (M).
Finding Directory Sizes (du)
Once you know *which* drive is full, how do you find the specific folder that is hoarding all your space? Is it your downloads folder, or maybe some hidden cache? We solve this mystery using the `du` (disk usage) command. - `du <directory>` lists the size of a folder and every subfolder inside it. - `du -sh <directory>` (where `-s` means "summary" and `-h` means "human-readable") calculates and prints a single, clean total size for that specific folder. **Why this matters**: If you run `du` without `-s`, it will dump a massive wall of text listing every single individual subdirectory and file recursively, rather than giving a single summary. The `-s` flag summarizes the total size of the folder, and `-h` makes it human-readable.
Checking Memory Usage (free)
Imagine your laptop starts lagging, web pages freeze, and switching apps feels painfully slow. This usually means your computer is running out of active memory (RAM). In Linux, we can check how much breathing room our system has using the `free` command. - The `free` command shows total, used, and available physical memory (RAM) and swap space. - Adding the `-h` flag (running `free -h`) formats the memory sizes into easy-to-read gigabytes (GB) and megabytes (MB) so you can tell if a program is eating up all your resources. **Why this matters**: If you run `free` without `-h`, memory usage is printed in raw kilobytes (e.g., `16323456` instead of `16G`), which is difficult to interpret quickly. The `-h` flag automatically scales the numbers to gigabytes (G) or megabytes (M) for easy reading.
System Uptime & Kernel Details
Imagine troubleshooting a server that started misbehaving and needing to know if it recently rebooted, or checking exactly what operating system version is running under the hood. We can query these system details in seconds: - The `uptime` command tells you exactly how long your machine has been running since its last boot, along with how busy it has been (system load). - The `uname -a` (unix name) command prints a full report of your system's kernel, platform name, and machine architecture. **Why this matters**: If you run `uname` without `-a`, it only outputs the basic operating system name (e.g., `Linux`). It leaves out critical details like the kernel version, platform name, and processor architecture. The `-a` flag prints all available system details in a single report.
7. Process Management
Listing Running Processes (ps)
Think of your operating system as a busy office where every employee (or running program) is assigned a unique name tag called a Process ID (PID). In Linux, we call these active programs **processes**, and we list them using the `ps` command. - Running `ps` by itself only shows programs running inside your current terminal window. - Running `ps aux` acts like a master office registry, listing every single active program running across the entire system, who started it, and how much CPU and memory it is using. **Why this matters**: If you run `ps` without `aux`, you will only see processes running in your current terminal window (usually just `bash` and `ps` itself). You won't see background services, system processes, or programs run by other users. The `aux` options reveal all running processes system-wide.
Interactive Process Monitor (top)
Imagine looking at a static photo of a highway versus watching a live traffic camera feed. While `ps` gives you a quick snapshot of what is running right now, `top` lets you watch your system's performance live. - The `top` command launches an interactive, real-time dashboard that updates every few seconds. It displays CPU usage, load averages, and dynamically ranks the most resource-heavy processes running at this exact moment.
Stopping Rogue Processes (kill)
Imagine an app on your phone freezes up, completely locking your screen, and you need to force-close it to get things running smoothly again. In Linux, we stop misbehaving or frozen programs by using the `kill` command followed by the program's Process ID (PID). - Running `kill 1234` sends a polite request asking the program to save its work and close down. - If it is frozen and ignores the polite request, `kill -9 1234` forces the operating system to shut it down instantly. We have a runaway process with PID `9999` hogging all our CPU right nowβlet's shut it down!
Running Jobs in the Background
Imagine trying to copy a massive folder to a USB drive, but while it copies, you want to keep working and typing other commands in the same window. In Linux, we can run time-consuming tasks in the "background" so they don't lock up our command line. - Adding an ampersand `&` to the end of a command (like `sleep 100 &`) tells the terminal to run it in the background and give you your prompt back immediately. - The `jobs` command shows what is currently running in the background. - The `fg` (foreground) command pulls a background task back to center stage.
8. Network Troubleshooting
Testing Connectivity (ping)
Imagine trying to load a webpage, but your browser spins endlessly, leaving you wondering if your home Wi-Fi is disconnected or if the website itself has crashed. In Linux, we test our basic network connection using the `ping` command. - The `ping` command sends tiny packets of data to a server (like `google.com`) and measures how many milliseconds it takes to receive a response. - On Linux, `ping` will keep running forever by default. To make it stop after a few attempts, we use the `-c` (count) flag, running `ping -c 3 google.com`. **Why this matters**: If you run `ping google.com` without `-c`, it will continue sending packets and printing output infinitely. You will have to manually interrupt it with `Ctrl+C` to run any other commands. The `-c 3` flag stops the command automatically after sending exactly 3 packets.
Network Interfaces & Local IP
Imagine setting up a network printer or sharing files with a friend's computer on the same Wi-Fi, and needing to know your machine's local IP address. In Linux, we inspect our network hardware and IPs using the `ip` command. - Running `ip addr` (or simply `ip a`) prints a list of all your network interface devices (like `eth0` for wired ethernet or `wlan0` for wireless) along with their assigned local IP addresses.
Downloading Web Files (curl)
Imagine wanting to download a file or grab the code of a setup script directly from a web server without opening a browser and clicking a "Download" button. In Linux, we fetch web data using `curl` (short for "Client URL"). - Running `curl <url>` downloads the page content and prints it right on your screen. - To save the downloaded content as a file instead of displaying it, we pair it with `>` redirection or the `-o` output flag.
9. Finding Files & Search
Finding Files by Name (find)
Imagine misplacing an important text file somewhere in your user folder and having to search through dozens of nested directories one-by-one. In Linux, we bypass manual digging by using the `find` utility as a lightning-fast system-wide search engine. - The `find` command searches through directory trees based on name, size, type, or date. - The syntax is `find <where> -name "<pattern>"`. E.g., `find . -name "*.txt"` searches the current directory and all subfolders for files ending in `.txt`. **Why this matters**: If you run `find . "*.log"` without `-name`, you will get the error: `find: paths must precede expression: '*.log'`. The `-name` flag is required to specify that the subsequent pattern should be matched against the filenames.
Checking Command History
Imagine you typed a long, complex network diagnostic command ten minutes ago, and now you need to run it again, but you can't remember the exact options or syntax. Instead of scratching your head or typing it all over, Linux remembers it for you! - The `history` command displays a numbered list of all commands you've recently executed. - You can quickly re-run any item by typing an exclamation point followed by its list number (like `!42` to re-execute command #42).
Consulting Manual Pages
Imagine trying to use a new command, but you aren't sure what flags it supports or how its inputs should be formatted. Instead of searching online, Linux has an official, comprehensive user manual built right into the terminal! - The `man` (manual) command followed by any utility name (e.g., `man ls`) opens a detailed reference guide. - Inside the guide, you scroll with the arrow keys, search with "/", and press `q` to close the manual and return to your prompt.
10. Services & Systemd
Controlling Services (systemctl)
Imagine hosting a website on your computer, but visitors get a "site cannot be reached" error because the background web server program isn't running. In Linux, background processes that start automatically and run in the background (like databases, firewalls, or web servers) are called **services**, and we manage them using `systemctl`. - The `systemctl status <service>` command checks if a service is active or stopped. - Since starting or stopping a service affects all users and the system's security, you must use `sudo` to run commands like `sudo systemctl start <service>` or `sudo systemctl stop <service>`.
System Logging (journalctl)
Now that you can start and stop background services with `systemctl`, how do you troubleshoot them when they fail? The `journalctl` utility lets you inspect system logs generated by services managed by systemd. - By default, `journalctl` shows all system logs. Because this can be massive, we filter them to stay focused. - The `-u <service>` option filters logs to only show messages from a specific service (e.g. `journalctl -u apache2`). - The `-n <number>` option displays only the most recent entries (e.g. `journalctl -n 5` for the last 5 logs). - The `-f` (follow) flag displays logs in real-time as they are written.
11. Terminal Text Editing
Editing Config Files (nano)
Imagine SSH-ing into a remote cloud server where you don't have a graphical desktop or cursor, and you need to quickly fix a line in a configuration file. In these scenarios, you must use a terminal text editor like `nano`. - Running `nano <filename>` loads a simple, lightweight text editor directly inside your shell window. - The shortcuts are always displayed at the bottom of the screen: press `Ctrl+O` to write out (save) your changes, and `Ctrl+X` to exit the editor.
12. Shell Scripting & Automation
Writing Your First Bash Script
Imagine having a list of 20 tasks that you have to run every single morning. Typing them out manually is tedious and leaves room for typos. In Linux, we bundle commands into a file called a shell script so we can execute them all at once! - Every script starts with a "shebang" (`#!/bin/bash`) on the very first line to tell the system which shell interpreter to use to run the file. - After saving your script, you make it runnable by granting it execute permission via `chmod 755 script.sh` and then running it with `./script.sh`.
Variables & Arguments ($1)
Imagine creating a personalized welcome message for a website. You wouldn't want to write a separate script for every single customer's name! Instead, you write one script that takes a name as input when you run it. - In bash scripts, variables like `$1`, `$2`, and so on hold the "arguments" or inputs you pass at the command line. - E.g., running `./greet.sh Alice` means `$1` inside the script will automatically contain the text "Alice". Similarly, `$#` keeps track of how many inputs the user provided.
Conditional Logic (if/else)
Imagine building a script that processes a CSV report, but it crashes if the report file doesn't actually exist on disk. To prevent errors, we write scripts that make decisions using `if/else` conditional logic. - We check conditions using brackets: `if [ -f "$1" ]; then ... fi`. - The `-f` flag checks if a path points to a file, while `-d` checks if it is a directory. The script branches its actions depending on whether the condition evaluates to true or false.
Automating with Loops
Imagine having a folder of 100 log files, and you need to make a backup copy of every single one. Copying them individually would be exhausting. In Linux, we use `for` loops to repeat the same action across a whole list of items automatically! - A `for` loop (like `for file in *.txt; do ... done`) iterates over every item that matches a pattern, processing them one after the other in a split second.
Reusable Logic (bash functions)
You've written loops and conditionals to automate actions in scripts. But as your scripts grow, copy-pasting the same logic over and over makes them hard to maintain. In bash, we can group commands into reusable functions. - To define a function, we declare it by name followed by parentheses and curly braces: `log_msg() { echo "msg"; }`. - Functions can receive arguments just like shell scripts, which are accessed using local position parameters `$1`, `$2`, etc. inside the function body. - To call a function, simply use its name like any other command: `log_msg "Backup started"`.
Scheduling Tasks (crontab)
Now that you have written robust shell scripts, you wouldn't want to log in at midnight just to run your backup helper. Linux provides the `cron` service to run commands or scripts automatically at specific times. - The cron service checks a scheduling table called `crontab`. - Each cron schedule has 5 fields representing time: `minute hour day-of-month month day-of-week` followed by the command. - E.g., `30 2 * * * /path/to/script.sh` runs a script every day at 2:30 AM. - We use `crontab -l` to list our active cron jobs, and `crontab <filename>` to load schedules from a file.
13. Advanced Text Processing
Stream Editing with sed
Imagine you have a huge database dump file, and you need to replace all occurrences of an old server IP address with a new one. Opening it in an editor might freeze your computer. In Linux, we edit text streams on the fly using `sed` (short for "stream editor"). - The basic syntax is `sed "s/old/new/g" file.txt` to find and replace text. - Adding the `-i` (in-place) flag saves the replacements directly back into the file itself, rather than just printing the modified text on screen. **Why this matters**: If you run `sed "s/port=80/port=8080/g" server.conf` without `-i`, it will only print the modified text to your terminal screen. The actual file remains completely unchanged. The `-i` (in-place) flag is necessary to save the changes directly back into the file.
Data Extraction with awk
Imagine receiving a large spreadsheet saved as plain text, where columns are separated by commas or spaces, and you only need to extract the very first column of data. In Linux, we parse structured columns of text using the powerhouse language `awk`. - By default, `awk` splits lines by whitespace, assigning column 1 to `$1`, column 2 to `$2`, and so on. - The `-F` flag lets you specify a custom separator (like `-F:` for colons). E.g., `awk -F: '{print $1}' /etc/passwd` extracts just the usernames from a colon-separated list. **Why this matters**: If you run `awk '{print $1}' /etc/shadow` without `-F:`, `awk` will split lines by whitespace (the default) rather than colons. Since shadow file lines don't have spaces, the entire line is treated as a single field, printing every user's full hash details. The `-F:` flag forces `awk` to split columns by colons instead.
Translating & Cutting Data
Imagine working with a CSV spreadsheet of transaction dates and names. You want to extract only the first column (dates) and convert all text to capital letters for consistency. In Linux, we can combine lightweight parsing tools in a pipeline: - The `cut` command slices out specific columns from structured text. E.g., `cut -d, -f1` splits lines by commas (`-d,`) and extracts the first column (`-f1`). - The `tr` (translate) command transforms characters from standard input, like swapping lowercase characters for uppercase (`tr "a-z" "A-Z"`). **Why this matters**: If you run `cut reports.csv` without `-d,` and `-f1`, you will get: `cut: you must specify a list of bytes, characters, or fields`. If you specify `-f1` but omit `-d,`, it defaults to tabs, meaning it won't split a CSV file and will just print the entire line. The `-d,` flag defines the comma as the column separator, and `-f1` tells it to extract only the first column.
14. Environment & Users
Managing Environment Variables
Imagine you are deploying a web application, and it needs to know whether to run in a safe local "development" sandbox or connect to the live "production" database. In Linux, we pass configurations like this to running programs using **environment variables**. - We use the `export` command to define a variable so that any programs started by our shell can read it. E.g., `export APP_ENV=production`. - To check or display a variable's value, we prefix its name with a dollar sign: `echo $APP_ENV`.
Archives & Compression (tar)
Imagine you have a folder containing 500 server logs, and you want to email it to a colleague or back it up to cloud storage. Sending 500 individual files is slow and inefficient. In Linux, we compress them into a single, compact zip-like file using `tar` (short for "tape archive"). - We create compressed archives using flags: `-c` (create), `-z` (compress with gzip), `-v` (verbose listing of files), and `-f` (specify filename). E.g., `tar -czvf backup.tar.gz folder/` bundles and zips the directory. **Why this matters**: If you run `tar -cz logs.tar.gz logs` without `-f`, you will get: `tar: Refusing to write archive contents to terminal`. The `-f` flag is critical because it tells `tar` to write the output to a file instead of sending raw binary archive data directly to your terminal. The `-c` and `-z` flags are also required to create and compress the archive respectively.
Inspecting the Environment
Imagine you are trying to debug a script that keeps failing because it can't find a program's path, or you want to see which user account is active in this terminal. In Linux, all these session-wide configurations are stored together. - The `env` command prints out a complete directory of all environment variables currently loaded in your active session, letting you verify configurations in one go.
Finding Commands (which)
Now that you are familiar with active environment variables like `PATH` (which stores the directories where Linux looks for commands), how do you find the exact file path of the program that runs when you type `ls` or `grep`? We use `which` to locate command binaries. - The `which` command searches the folders listed in your `$PATH` variable and prints the absolute path of the binary executed when the command is run (e.g. `which ls` outputs `/bin/ls`). - This is useful to find where a tool is installed or resolve conflicts between multiple versions of the same tool.
Custom Shell Shortcuts (alias)
Typing long commands with multiple flags can get exhausting. In Linux, we can create custom shortcuts called aliases. For example, you can map `ll` to run `ls -la` automatically. - To create a temporary alias, run `alias name='command'` (e.g. `alias ll='ls -la'`). - Running `alias` without arguments lists all active aliases in the current session. - To make aliases permanent across reboots, they are typically written to `.bashrc` or `.bash_profile` configuration files.
15. Advanced Filesystem
Creating Links (ln -s)
Imagine you have a config file buried deep in a nested folder, say `/var/www/html/configs/app/settings.conf`, but you need to edit it constantly. Instead of typing the long folder path every time, you want a quick desktop shortcut. In Linux, we do this by creating links. - **Hard Link**: A direct clone pointing to the raw file data. If you delete the original file, the link still works. - **Symbolic Link (Soft Link)**: A path-based shortcut (just like Windows shortcuts). If you delete the original file, the link breaks. We create them using `ln -s target link_name`. **Why this matters**: If you run `ln logs/app.log app_link.log` without `-s`, you will create a hard link instead of a symbolic shortcut. If the files reside on different disk partitions, you will get: `ln: failed to create hard link: Invalid cross-device link`. The `-s` flag creates a flexible symbolic link (shortcut) that works across different drives and directories.
Processing Search Results (xargs)
Imagine you ran a search that returned 100 temporary files, and now you want to delete all of them. The search output is just a list of text names on your screenβhow do you feed those names as direct inputs to the delete command? In Linux, we bridge this gap using `xargs`. - The `xargs` (execute arguments) command takes lines of standard input (like the file list from `find`) and feeds them one by one as arguments to another command. - E.g., `find . -name "*.tmp" | xargs rm` finds all temporary files and removes them all in a single sweep.
16. Remote Access & User Admin
User Administration (useradd & passwd)
So far, you've been working as the `learner` user. But in real-world servers, sysadmins must manage multiple accounts. Let's learn how to add new users and set their passwords. - The `useradd` command creates a brand new user account. Since creating accounts affects system security, it must be run with superuser privileges (e.g. `sudo useradd deployer`). - The `passwd` command sets or changes a user's password. Run as `sudo passwd deployer` to set the deployer user's password.
Switching Security Contexts (su)
Now that you've created the `deployer` account, how do you log into it locally to test its environment? In Linux, we use the `su` (substitute user) command to switch accounts without logging out. - The `su <username>` command switches the current terminal shell to that user's session. - When switched, running `whoami` will reflect the new user name. - To return to your original user account session, type `exit` or press `Ctrl+D`.
Secure Shell Access (ssh)
Switching users locally is useful, but in cloud computing, servers live in remote data centers. To connect to them securely over the network, we use `ssh` (Secure Shell). - The `ssh` command encrypts the connection between your machine and a remote host to prevent eavesdropping. - Syntax: `ssh user@hostname` or `ssh user@ip_address` (e.g. `ssh admin@192.168.1.100`). - The first connection will prompt you to verify the remote host's authenticity by displaying a unique ECDSA fingerprint. **Note:** Since this is a browser-based sandbox, there's no real remote server to connect to. Running this command will show you the expected real-world output pattern (host verification, connection, session) instantly, rather than an actual live interactive session. In a real terminal, ssh would drop you into a genuinely separate remote shell until you type `exit`.
Secure File Transfer (scp)
Now that you know how to log into a remote server via SSH, how do you copy a local file (like a backup archive) to it? The `scp` (secure copy) command copies files securely between hosts using SSH under the hood. - The syntax is `scp source_path user@host:destination_path`. - E.g., `scp log.txt admin@192.168.1.100:/tmp/` copies the local `log.txt` file to the remote `/tmp/` folder. **Note:** Just like with ssh, there's no real remote server here β running this command confirms your local file exists and shows you the expected transfer output, but doesn't actually send data anywhere.
Who Am I and Where Am I?.
Command Reference
Verification Checklist
Revealed Hints
File Explorer
About BashQuest.
A free, open-source Linux learning playground designed to teach you shell commands through actual browser-based filesystem interactions.
What is BashQuest?
BashQuest is a free, interactive command-line learning simulator built specifically for hands-on education. Unlike online video courses where you passively watch others work, BashQuest forces you to learn by actually typing commands.
Under the hood, it features a custom-built, simulated terminal and directory structure. The tasks you execute directly modify a local virtual filesystem that tests and validates your work in real-time, giving you immediate feedback.
Why I built this.
When I first started learning Linux, I was terrified of running the wrong command and breaking my system. Most tutorials are either boring videos or dry textbooks that don't let you actually practice.
I wanted to build a hands-on, zero-risk environment where beginners could learn by doing. I engineered BashQuest using Astro and Vanilla JS so it runs entirely client-sideβmeaning it's lightning fast, requires no servers, and protects your privacy.
Practice Linux Commands Online, with Instant Feedback
Learning the command line is easier when you can try things immediately. BashQuest provides an interactive terminal sandbox where you can run real shell-style commands against a simulated Linux filesystem. Instead of watching videos or reading static examples, you build skill by completing short quests that guide you step-by-stepβthen you verify your output right inside the browser.
Each quest focuses on a practical command-line skill: exploring directories, listing files, searching text, using pipes, understanding permissions, and writing small bash scripts. As you progress, the tasks become more realistic so your learning transfers to your real computer.
A Virtual Linux Terminal Simulator
BashQuest acts like a Linux terminal emulator, but with structured learning built in. The experience is gamified: you unlock quests in a curriculum tree, earn XP, and collect badges. That means every practice session has a clear purpose.
The virtual environment is safe. You can experiment freely because your workspace is simulated. If you run a risky command or make a mistake, it stays within the interactive terminal sandbox and does not affect your machine.
Why Practice Helps You Improve Faster
The fastest way to improve at the terminal is repetition with structure. BashQuest gives you both: short command challenges and a curriculum that keeps you moving forward. You can focus on learning topics one at a time, while still working within a single consistent environment.
Because the simulator is interactive, you can develop real muscle memory: typing commands, reading output, and iterating until you get the exact result. Over time, these steps become automatic.
From One-Liners to Bash Scripts
BashQuest is made for practicing bash scripts online and for understanding how bash command-line tools work together. You will work through tasks that gradually expand your abilities:
- β Explore and navigate filesystems
- β Manipulate text with patterns
- β Pipe & filter command output
- β Practice matching and wildcards
- β Manage file permissions
- β Test simple shell scripts
What you'll learn.
Our progressive curriculum covers 16 core Linux administration skill sets: