Home / Side Quests / Linux Basics

Linux Basics for Developers

Estimated time: 3–4 hours | Difficulty: Beginner

Side Quest

What You Will Learn

  • Understand why Linux matters for every developer, not just sysadmins
  • Navigate the file system confidently using the terminal
  • Create, move, copy, and delete files and directories from the command line
  • Search through files and logs with find, grep, and piping
  • Understand Linux file permissions and why they matter for deployments
  • Manage processes and services like MySQL
  • Install software using a package manager
  • Connect to remote servers using SSH
  • Build a personal cheat sheet of essential commands

1. Why Linux?

Here is a number that should get your attention: over 96% of the top one million web servers in the world run Linux. That means virtually every website you have ever visited — Google, Amazon, Netflix, GitHub, your bank, your favorite social media platform — is running on a Linux server somewhere. When you deploy a Spring Boot application to the cloud, it will almost certainly land on a Linux machine. When you spin up a Docker container, it runs Linux inside. When you set up a CI/CD pipeline, the build agents are running Linux.

But Linux is not just for servers. Android, which powers the majority of smartphones on the planet, is built on top of the Linux kernel. Chromebooks run Linux. The Steam Deck runs Linux. Many Internet of Things devices run Linux. It is everywhere.

And even if you are on a Mac, you are closer to Linux than you might think. macOS is built on Unix, and Unix is the ancestor of Linux. The terminal commands you will learn in this lesson work almost identically on both systems. The skills transfer directly.

If you are on Windows, you have an incredible tool called WSL — Windows Subsystem for Linux. WSL gives you a full Linux environment running right inside Windows, with access to a real bash terminal, a real file system, and real Linux tools. No virtual machine, no dual booting, no hassle. Microsoft built it because they recognized that developers need Linux, even when they prefer Windows for their desktop.

Let us set it up. If you are on Windows, open PowerShell as an administrator and run:

wsl --install

That single command installs WSL 2 with Ubuntu as the default distribution. It will ask you to restart your computer. After rebooting, a terminal window will open asking you to create a username and password for your Linux environment. Choose something simple and remember it — you will use it whenever you need administrator privileges inside Linux.

If you are on a Mac, you already have everything you need. Open Terminal.app (you can find it in Applications → Utilities, or just press Cmd + Space and type "Terminal"). The macOS terminal gives you a Unix shell that accepts nearly all the same commands you will learn here.

If you are already running Linux on your desktop — welcome home. Open your terminal and let us get started.

From this point on, every command in this lesson should be typed into your terminal. Do not copy and paste. Typing each command builds muscle memory. You want these commands to become as natural as typing a URL into a browser. By the end of this side quest, the terminal will feel like a superpower, not a scary black screen.

2. Getting Around

The first thing you need to know in any new environment is how to figure out where you are, what is around you, and how to move. In a graphical file manager you do this with your eyes — you see folders, you double-click to open them, you click the back button. In the terminal, you do the exact same things, but with short commands.

Where Am I?

The pwd command stands for print working directory. It tells you exactly where you are in the file system right now:

pwd

You will see something like /home/yourname on Linux or /Users/yourname on macOS. This is your home directory — your personal space on the system. Think of it like your "Documents" folder, but for everything.

What Is Here?

The ls command lists the contents of the current directory:

ls

You will see file and folder names. But this basic view hides a lot. To see everything, including hidden files and detailed information, use:

ls -la

The -l flag means "long format" — it shows permissions, owner, size, and modification date. The -a flag means "all" — it includes files that start with a dot (like .bashrc or .gitconfig). Hidden files in Linux are simply files whose names start with a period. There is no special "hidden" attribute like on Windows. You will use ls -la constantly. Get used to typing it.

Moving Around

The cd command stands for change directory. It is how you move through the file system:

# Move into a directory
cd Documents

# Go up one level (back to the parent directory)
cd ..

# Go directly to your home directory from anywhere
cd ~

# Go to the root of the entire file system
cd /

The .. means "one directory up." You can chain them: cd ../../../ goes up three levels. The ~ (tilde) is a shortcut that always means your home directory, no matter where you are. And / by itself is the root of the file system — the very top of the tree.

Creating Directories and Files

The mkdir command makes directories (folders), and touch creates empty files:

# Create a directory
mkdir my-project

# Create nested directories in one command
mkdir -p my-project/src/main/java

# Create an empty file
touch README.md

# Create multiple files at once
touch index.html style.css app.js

The -p flag on mkdir is essential. Without it, mkdir will fail if the parent directory does not exist. With -p, it creates the entire path, no matter how many levels deep. You will use this every time you set up a Java project structure.

Tab Completion — Your Most Useful Habit

This is not a command. It is the single most important habit you will develop in the terminal. When you start typing a file name or directory name, press the Tab key. The terminal will auto-complete the rest of the name for you. If there are multiple matches, press Tab twice to see all the options.

Try it right now. Type cd Doc and then press Tab. The terminal will complete it to cd Documents/ (assuming that directory exists). This saves time, prevents typos, and confirms that the file or directory you are targeting actually exists. If Tab does nothing, the name you are typing does not match anything — which means you have a typo or you are in the wrong directory.

Use Tab completion on every single command. Professional developers do this instinctively. It is faster than typing and more reliable than memory.

Practice: Build a Project Structure

Let us put all of this together. Using only the terminal, create the following project structure. Do not use a graphical file manager. Do not use your code editor. Type every command.

# Start from your home directory
cd ~

# Create the project directory and navigate into it
mkdir linux-practice
cd linux-practice

# Create the full directory structure
mkdir -p src/main/java/com/example
mkdir -p src/main/resources/templates
mkdir -p src/main/resources/static/css
mkdir -p src/main/resources/static/js
mkdir -p src/test/java/com/example

# Create some files
touch src/main/java/com/example/Application.java
touch src/main/java/com/example/HomeController.java
touch src/main/resources/application.properties
touch src/main/resources/templates/index.html
touch src/main/resources/static/css/style.css
touch src/main/resources/static/js/app.js
touch src/test/java/com/example/ApplicationTest.java
touch README.md
touch .gitignore

# Verify your work
ls -la
ls -R

The ls -R command lists everything recursively — it shows the contents of the current directory and every subdirectory inside it. You should see the entire tree you just created. Congratulations — you just set up a Spring Boot project structure entirely from the terminal. That is a real skill.

3. Working with Files

Now that you can navigate and create files, you need to learn how to read them, move them, copy them, and yes, delete them. These are the commands you will use dozens of times per day as a developer.

Reading Files

The cat command prints the entire contents of a file to your terminal:

# Print the entire file
cat README.md

# Print with line numbers
cat -n Application.java

cat works great for short files. But what about a file with thousands of lines? That is where less comes in:

# Open a file in a scrollable viewer
less application.properties

Inside less, you can scroll up and down with the arrow keys, jump to the top with g, jump to the bottom with G, search for text by typing /searchterm, and quit by pressing q. It is like a read-only text editor built into the terminal.

Sometimes you only need to see the beginning or end of a file. That is what head and tail are for:

# Show the first 10 lines
head server.log

# Show the first 20 lines
head -20 server.log

# Show the last 10 lines
tail server.log

# Show the last 50 lines
tail -50 server.log

# FOLLOW the file in real time (watch new lines appear)
tail -f server.log

That last one, tail -f, is a game-changer. The -f stands for follow. It keeps the terminal open and shows new lines as they are written to the file. This is how developers watch server logs in real time. When you run a Spring Boot application and want to see what is happening, you open a second terminal and run tail -f on the log file. You see errors the instant they happen. Press Ctrl + C to stop following.

Copying, Moving, and Renaming

# Copy a file
cp README.md README-backup.md

# Copy a directory and everything in it (recursive)
cp -r src/ src-backup/

# Move a file (also used for renaming)
mv README.md docs/README.md

# Rename a file (mv with the same directory)
mv old-name.txt new-name.txt

Notice that mv serves double duty: it both moves and renames files. If the destination is a different directory, the file moves. If the destination is the same directory with a different name, the file is renamed. There is no separate "rename" command in Linux.

Deleting Files — With Great Caution

# Delete a file
rm old-file.txt

# Delete a file and ask for confirmation first
rm -i important-file.txt

# Delete an empty directory
rmdir empty-folder/

# Delete a directory and everything inside it
rm -r my-folder/

# THE DANGEROUS ONE — force delete everything recursively
rm -rf my-folder/

Let us talk about rm -rf. This is the most powerful and most dangerous command in Linux. The -r flag means recursive (delete everything inside), and the -f flag means force (do not ask for confirmation, do not complain about missing files, just delete). There is no trash can in the Linux terminal. There is no undo. There is no "Are you sure?" dialog. When you rm -rf something, it is gone. Forever.

The classic horror story every Linux user has heard (and some have lived through) is accidentally running rm -rf / — which attempts to delete literally everything on the entire system. Modern Linux distributions have safeguards against this specific command, but variations of it can still cause catastrophic damage. The rule is simple: always double-check your rm commands before pressing Enter. Read the path. Make sure it is correct. Make sure you are in the right directory. Then press Enter.

A safer habit: run ls first to see what you are about to delete, then change ls to rm -r:

# First, see what is there
ls old-project/

# Okay, that is what I expected. Now delete it.
rm -r old-project/

Searching for Files and Content

Two of the most powerful commands in Linux are find and grep. find searches for files by name, type, size, or other attributes. grep searches for text inside files.

# Find all Java files in the current directory and subdirectories
find . -name "*.java"

# Find all files modified in the last 24 hours
find . -mtime -1

# Find all empty directories
find . -type d -empty

# Search for the word "TODO" in all files under src/
grep -r "TODO" src/

# Search for "TODO" with line numbers and file names
grep -rn "TODO" src/

# Case-insensitive search
grep -ri "error" logs/

# Search only in Java files
grep -rn "public class" --include="*.java" src/

Piping — Connecting Commands Together

This is where the terminal starts to feel truly powerful. The pipe operator (|) takes the output of one command and feeds it as input to the next command. You can chain as many commands as you want, building a pipeline that processes data step by step.

# Find all ERROR lines in a log file, show the last 20
cat server.log | grep "ERROR" | tail -20

# Count how many TODO comments are in your project
grep -r "TODO" src/ | wc -l

# Find all Java files and count them
find . -name "*.java" | wc -l

# Show the 10 largest files in the current directory
ls -lS | head -10

# Find all unique ERROR types in a log
cat server.log | grep "ERROR" | sort | uniq

The wc -l command counts lines. sort sorts lines alphabetically. uniq removes consecutive duplicate lines (which is why you sort first). Each of these commands does one small thing, but piped together they become incredibly powerful. This is the Unix philosophy: small tools that do one thing well, connected together to solve complex problems.

That first example — cat server.log | grep "ERROR" | tail -20 — is something you will use in your career regularly. When a production application is misbehaving and the log file is 500,000 lines long, you do not open it in a text editor. You pipe it through grep to find the errors, then tail to see only the most recent ones. In seconds, you have exactly the information you need.

Output Redirection

Pipes send output to another command. But what if you want to save output to a file? That is what redirection operators do:

# Write output to a file (overwrites if the file exists)
grep -rn "ERROR" server.log > errors.txt

# Append output to a file (does not overwrite)
grep -rn "WARNING" server.log >> errors.txt

# Redirect errors to a file
find / -name "*.conf" 2> /dev/null

# Save both output and errors
./build.sh > build-output.txt 2>&1

The > operator writes to a file, replacing whatever was there before. The >> operator appends to the end without erasing existing content. The 2> redirects error messages specifically. And 2>&1 combines errors and regular output into the same stream. That last one is useful when you want a complete log of everything a command produced, including any errors.

Redirecting to /dev/null is a special trick. /dev/null is a black hole — anything sent to it disappears. So 2> /dev/null means "throw away all error messages." This is useful when a command produces many "Permission denied" errors that you do not care about and you just want the actual results.

4. Permissions

Every file and directory in Linux has permissions that control who can read it, write to it, and execute it. This system is fundamental to Linux security, and it is something you will encounter constantly as a developer — especially when deploying applications or running scripts.

Understanding Permission Output

Run ls -l on any directory and look at the first column. You will see something like this:

-rwxr-xr--  1  sarah  developers  4096  Jan 15 09:30  deploy.sh
drwxr-xr-x  5  sarah  developers  4096  Jan 15 09:30  src/
-rw-r--r--  1  sarah  developers  1234  Jan 15 09:30  README.md

That first column, -rwxr-xr--, is the permission string. Let us decode it:

Each set of three has three possible letters:

So -rwxr-xr-- means:

Changing Permissions

The chmod command changes permissions. The most common use case you will encounter is making a script executable:

# Make a script executable
chmod +x deploy.sh

# Now you can run it
./deploy.sh

# Remove execute permission
chmod -x deploy.sh

# Give the owner read and write, group read only, others nothing
chmod 640 config.properties

# Give everyone read, write, and execute (NOT recommended for most files)
chmod 777 script.sh

The numeric system (like 640) uses three digits: owner, group, other. Each digit is the sum of: read (4) + write (2) + execute (1). So 640 means: owner gets read+write (6), group gets read (4), others get nothing (0). You will see chmod 755 and chmod 644 most often in the real world.

Changing Ownership

The chown command changes who owns a file. You will need this when deploying web applications:

# Change the owner of a file
sudo chown www-data:www-data /var/www/html/index.html

# Change the owner of a directory and everything inside it
sudo chown -R appuser:appuser /opt/myapp/

Notice the sudo in front. Changing file ownership requires administrator privileges. sudo stands for "superuser do" — it runs the command as the root (admin) user. You will be asked for your password.

Why This Matters

Permissions are not academic. Here are real scenarios you will encounter:

When something is not working on a Linux server, check the permissions first. It is one of the most common causes of deployment issues.

5. Processes and Services

Every program running on a Linux system is a process. Your terminal is a process. Your web browser is a process. Your Spring Boot application is a process. MySQL is a process. Understanding how to see what is running, stop what is stuck, and manage long-running services is essential.

Viewing Running Processes

# Show all running processes with full detail
ps aux

# Show only processes matching a name
ps aux | grep java

# Show only your processes
ps aux | grep $USER

# Interactive process viewer (like Task Manager)
top

# Better interactive viewer (install with: sudo apt install htop)
htop

ps aux gives you a snapshot of everything running on the system right now. Each line shows the process ID (PID), the user running it, CPU and memory usage, and the command. When you pipe it through grep, you can find specific processes instantly. If your Spring Boot app is running and you want to confirm it, ps aux | grep java will show you.

top is like Windows Task Manager for the terminal. It updates in real time, showing you which processes are using the most CPU and memory. Press q to quit. htop is a more modern, colorful version of top — if your system has it, use it instead.

Stopping Processes

# Kill a process by its PID (graceful shutdown)
kill 12345

# Force kill a process that will not stop
kill -9 12345

# Kill all processes matching a name
killall java

# Find the PID of a process
pgrep -f "spring-boot"

A regular kill sends a polite "please stop" signal (SIGTERM). The process gets a chance to clean up — close database connections, finish writing files, save state. kill -9 sends SIGKILL, which is an immediate, forceful termination. The process does not get to clean up. Use kill -9 only when a process is completely stuck and regular kill does not work.

Managing Services

A service is a process that runs in the background, starts automatically when the system boots, and keeps running until you tell it to stop. MySQL is a service. Nginx is a service. On modern Linux systems, you manage services with systemctl:

# Start MySQL
sudo systemctl start mysql

# Stop MySQL
sudo systemctl stop mysql

# Restart MySQL (stop then start)
sudo systemctl restart mysql

# Check if MySQL is running
systemctl status mysql

# Make MySQL start automatically on boot
sudo systemctl enable mysql

# Prevent MySQL from starting on boot
sudo systemctl disable mysql

If you followed the earlier lessons and installed MySQL, you used systemctl without necessarily understanding what it does. Now you know. The status command is especially useful — it shows whether the service is running, when it started, and any recent log messages. When MySQL will not connect and you are not sure why, systemctl status mysql is your first stop.

Running Programs in the Background

Sometimes you want to run a command that takes a long time, and you do not want it to block your terminal. There are several ways to do this:

# Run a command in the background with &
java -jar myapp.jar &

# Run a command that survives closing the terminal
nohup java -jar myapp.jar &

# Use screen for persistent terminal sessions
screen -S myapp
# (run your commands inside screen)
# Press Ctrl+A then D to detach
# Reattach later with:
screen -r myapp

# Use tmux (modern alternative to screen)
tmux new -s myapp
# (run your commands inside tmux)
# Press Ctrl+B then D to detach
# Reattach later with:
tmux attach -t myapp

The & at the end of a command makes it run in the background, freeing up your terminal. But if you close the terminal, the process dies. nohup (no hang up) prevents that — the process keeps running even after you log out. This is how you would run a Spring Boot app on a server that does not have a service configuration yet.

screen and tmux are terminal multiplexers. They let you create persistent terminal sessions that survive disconnection. You SSH into a server, start a screen or tmux session, run your commands, detach, and log out. The session keeps running. When you SSH back in later, you reattach and everything is exactly where you left it. This is invaluable for long-running tasks on remote servers.

6. Package Management

On Windows, when you want to install a program, you go to a website, download an installer, double-click it, click "Next" five times, and hope it does not install a toolbar in your browser. On Linux, you use a package manager. It is faster, safer, and keeps everything up to date.

On Ubuntu and Debian-based systems (including WSL with Ubuntu), the package manager is called apt:

# Update the list of available packages
sudo apt update

# Install a package
sudo apt install htop

# Install multiple packages at once
sudo apt install curl wget git

# Upgrade all installed packages to their latest versions
sudo apt upgrade

# Remove a package
sudo apt remove htop

# Remove a package and its configuration files
sudo apt purge htop

# Search for packages
apt search "text editor"

# Show information about a package
apt show nginx

The sudo apt update command does not install or upgrade anything. It just refreshes the list of what is available, like checking the menu at a restaurant. You should run it before installing anything new so you get the latest version.

Think about what you have already installed in this course. MySQL? You installed it with sudo apt install mysql-server. Java? You installed it with sudo apt install openjdk-21-jdk. Git? You installed it with sudo apt install git. Every time, you used the package manager. It downloaded the software from trusted repositories, put the files in the right places, set up the right permissions, and configured everything automatically. No websites, no installers, no "Next Next Next Finish."

Where Did It Go?

When you install a program, how do you know where it ended up? The which command tells you:

# Where is java?
which java
# /usr/bin/java

# Where is git?
which git
# /usr/bin/git

# Where is mysql?
which mysql
# /usr/bin/mysql

Most system-installed programs live in /usr/bin/. But how does the terminal know to look there? That is what $PATH is for.

Understanding $PATH

The $PATH variable is a list of directories that the terminal searches through when you type a command. When you type java, the terminal does not search your entire hard drive for a program called "java." It only looks in the directories listed in $PATH, in order, and uses the first match it finds.

# See your current PATH
echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

The directories are separated by colons (:). When you type java, the terminal checks /usr/local/sbin/java, then /usr/local/bin/java, then /usr/sbin/java, then /usr/bin/java (found it!), and uses that one.

If you ever install a program and the terminal says "command not found," it almost always means the program is not in a directory listed in $PATH. The fix is either to add its directory to your $PATH, or to call it with its full path.

To add a directory to your $PATH, edit your ~/.bashrc file and add a line like this:

# Add a custom directory to PATH
export PATH="$PATH:/opt/my-program/bin"

This appends your custom directory to the end of the existing $PATH. After saving the file, run source ~/.bashrc to apply the change. Understanding $PATH saves you from a lot of confusion — "command not found" is one of the most common errors beginners encounter, and it almost always has a simple $PATH fix.

7. SSH and Remote Servers

Everything you have learned so far has been on your local machine. But in the real world, your application does not run on your laptop. It runs on a server — a computer in a data center somewhere, with no monitor, no keyboard, and no mouse. The only way to interact with it is through the terminal, using SSH.

SSH stands for Secure Shell. It gives you a terminal on a remote computer. You type commands on your laptop, and they execute on the server. It is as if you teleported your terminal to a machine thousands of miles away.

# Connect to a remote server
ssh username@192.168.1.100

# Connect to a server by hostname
ssh deploy@myapp.example.com

# Connect on a specific port (default is 22)
ssh -p 2222 username@server.example.com

The first time you connect to a server, SSH will show you the server's "fingerprint" and ask if you trust it. Type yes. After that, it will ask for your password. Once authenticated, you have a terminal on that remote machine. Every command you type now runs on the server, not your laptop. Type exit to disconnect and return to your local terminal.

SSH Keys vs. Passwords

Typing a password every time you connect is tedious and less secure. The professional approach is to use SSH keys — a pair of cryptographic keys that authenticate you automatically. It is like having a lock (on the server) and a key (on your laptop) instead of a password.

# Generate an SSH key pair
ssh-keygen -t ed25519 -C "your.email@example.com"
# Press Enter to accept the default file location
# Enter a passphrase (or press Enter for none)

# Copy your public key to the server
ssh-copy-id username@server.example.com

# Now you can connect without a password
ssh username@server.example.com

The ssh-keygen command creates two files: a private key (~/.ssh/id_ed25519) that stays on your computer and must never be shared, and a public key (~/.ssh/id_ed25519.pub) that you put on any server you want to access. The ssh-copy-id command does this for you automatically.

Remember the permissions lesson? Your private key must have strict permissions: chmod 600 ~/.ssh/id_ed25519. If anyone else can read it, SSH will refuse to use it. Security is built into the system at every level.

Transferring Files

You will often need to copy files between your laptop and a server. scp (secure copy) uses the same SSH connection to transfer files:

# Copy a file from your laptop to the server
scp myapp.jar deploy@server.example.com:/opt/myapp/

# Copy a file from the server to your laptop
scp deploy@server.example.com:/var/log/app.log ./local-copy.log

# Copy an entire directory
scp -r config/ deploy@server.example.com:/opt/myapp/config/

The syntax is scp source destination, where remote locations use the format user@host:path. The -r flag works the same as with cp — it copies directories recursively.

Preview: Deploying a Spring Boot App

Here is what deploying a Spring Boot application to a VPS (Virtual Private Server) looks like, using everything you have learned in this lesson:

# 1. Build your application locally
./mvnw clean package -DskipTests

# 2. Copy the JAR file to your server
scp target/resumator-0.0.1-SNAPSHOT.jar deploy@myserver.com:/opt/resumator/

# 3. SSH into the server
ssh deploy@myserver.com

# 4. Stop the old version
sudo systemctl stop resumator

# 5. Start the new version
sudo systemctl start resumator

# 6. Check that it is running
systemctl status resumator

# 7. Watch the logs
tail -f /var/log/resumator/app.log

Every single command in that deployment sequence uses skills from this lesson: scp for file transfer, ssh for remote access, systemctl for service management, and tail -f for log monitoring. This is what real-world deployment looks like. It is not scary — it is just terminal commands you already know.

8. The Developer's Daily Commands

You now know the fundamentals. Let us bring it all together with a quick reference of the commands you will use most often, plus some tips for making the terminal truly yours.

Quick Reference: 20 Most-Used Commands

# Navigation
pwd                       # Where am I?
ls -la                    # What is here?
cd directory/             # Go to a directory
cd ..                     # Go up one level
cd ~                      # Go home

# File Operations
cat file.txt              # View a file
less file.txt             # Scroll through a file
touch newfile.txt         # Create an empty file
mkdir -p path/to/dir      # Create directories
cp source dest            # Copy
mv source dest            # Move or rename
rm file.txt               # Delete a file
rm -r directory/          # Delete a directory

# Searching
find . -name "*.java"     # Find files by name
grep -rn "pattern" src/   # Search inside files

# System
ps aux | grep process     # Find running processes
kill PID                  # Stop a process
sudo apt install package  # Install software
chmod +x script.sh        # Make a file executable
ssh user@server           # Connect to remote server

Customizing Your Terminal

Your terminal has a configuration file that runs every time you open a new terminal window. On most Linux systems with bash, it is ~/.bashrc. On macOS with zsh, it is ~/.zshrc. You can edit this file to customize your experience:

# Open your bash configuration file
nano ~/.bashrc

# ---- Add these lines at the bottom ----

# Aliases — shortcuts for commands you type often
alias ll='ls -la'
alias gs='git status'
alias gp='git push'
alias gc='git commit -m'
alias cls='clear'
alias ..='cd ..'
alias ...='cd ../..'

# A better prompt that shows your current directory and git branch
parse_git_branch() {
    git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\u@\h \[\033[32m\]\w\[\033[33m\]\$(parse_git_branch)\[\033[00m\] $ "

# Always show colors in ls
alias ls='ls --color=auto'

# Make grep output colorful
alias grep='grep --color=auto'

# Safety nets — ask before overwriting or deleting
alias cp='cp -i'
alias mv='mv -i'

# ---- Save and exit (Ctrl+O, Enter, Ctrl+X in nano) ----

After editing, apply your changes without reopening the terminal:

# Reload your configuration
source ~/.bashrc

Aliases are shortcuts. Instead of typing ls -la every time, you can just type ll. Instead of git status, just gs. These small shortcuts add up to massive time savings over a career. Every experienced developer has a personalized set of aliases.

The PS1 variable controls your command prompt — what you see before the cursor. The example above shows your username, hostname, current directory (in green), and the current git branch (in yellow). This is incredibly useful because you always know exactly where you are and what branch you are working on.

Essential Keyboard Shortcuts

These shortcuts work in almost every terminal and will speed up your workflow enormously:

The Ctrl + R shortcut deserves special attention. Imagine you ran a complex find command twenty minutes ago and need it again. Instead of retyping the whole thing, press Ctrl + R and type a few characters from that command. The terminal will search your history and show the most recent match. Press Enter to run it, or Ctrl + R again to see older matches. Once you start using this, you will wonder how you ever lived without it.

The Terminal Is Your Most Powerful Tool

Here is a truth that takes most developers a while to accept: the terminal is the most powerful tool on your computer. Your IDE is nice. Your graphical git client is convenient. Your file manager works fine. But the terminal can do everything they can do, plus a thousand things they cannot.

You can write a one-line command that finds every Java file in your project containing the word "deprecated," counts them, and saves the list to a report. You can watch a server log in real time, filter it to only show errors from the last hour, and pipe those errors to a file for later analysis. You can SSH into five servers, deploy your application, restart services, and verify health checks — all from the same terminal window using tmux.

The graphical tools will always be there when you want them. But the developers who are truly productive — the ones who can solve problems quickly, automate tedious tasks, and manage complex systems — they live in the terminal. And now, so can you.

Knowledge Check

1. You write a deploy script called deploy.sh and try to run it with ./deploy.sh, but the terminal says "Permission denied." What is the most likely fix?

Correct! When you create a new file in Linux, it does not have execute permission by default. The chmod +x deploy.sh command adds execute permission, allowing you to run the script with ./deploy.sh. Linux does not use file extensions like .exe to determine if a file is executable — it uses the permission system. While sudo would technically work, it runs the script with full administrator privileges, which is unnecessary and potentially dangerous for a simple deploy script.

2. Your Spring Boot application is running on a server and you want to see error messages as they happen in real time. Which command should you use?

That's right! tail -f follows the file in real time, displaying new lines as they are written. The -f flag stands for "follow." This is the standard way developers monitor server logs during development and deployment. cat dumps the entire file at once and exits. head shows the beginning of the file and does not have a -f option. grep searches existing content but does not follow new output. For filtering errors in real time, you could combine them: tail -f /var/log/app.log | grep "ERROR".

3. What does the pipe operator (|) do in the command cat server.log | grep "ERROR" | tail -20?

Correct! The pipe operator takes the standard output of the command on its left and passes it as standard input to the command on its right. In this example, cat server.log outputs the entire file. That output is piped to grep "ERROR", which filters it to only lines containing "ERROR." Those filtered lines are then piped to tail -20, which shows only the last 20 of them. The result is the 20 most recent error messages from the log. This is the Unix philosophy in action: small, focused tools chained together to solve specific problems.

Deliverable

Create a Linux command cheat sheet using only the terminal. Here is how:

# Create the cheat sheet file
nano ~/linux-cheatsheet.txt

Inside this file, organize the commands you learned into categories. Include the command, a short description, and an example for each. Your cheat sheet should cover:

This cheat sheet is for you. Write it in your own words. Add notes about things that confused you or things you want to remember. Pin it next to your monitor or keep it open in a terminal tab. Over the next few weeks, every time you discover a new command or a useful flag, add it to your cheat sheet. By the end of this course, it will be one of your most valuable references.

Beyond the cheat sheet, you should be able to:

The terminal is not something you learn once and move on from. It is a skill that deepens over your entire career. Every week you will discover a new command, a new flag, a new way to pipe things together. The foundation you built today makes every future discovery easier. Welcome to Linux.

Finished this side quest?

← Back to Side Quests