Learn Basic Shell Scripting with Bash

Write four Bash scripts that automate file checks and system reporting.

Introduction

30 Second Summary

Every time you repeat the same commands in a terminal, you are doing work a script could handle for you in seconds. Scripting turns a sequence of manual steps into a single command you run whenever you need it.

In this project, you will write four Bash scripts from scratch, each one building on the last. You will start with a simple greeting, add interactivity, pull live system data, and finish with a script that validates files before processing them.

What You'll Build

A file validation tool that checks whether a path exists, reports its size and contents, and exits gracefully when something goes wrong.

By the end of this project, you'll have:

  • A working shell script you can run from the terminal to see your own greeting printed back at you.
  • An interactive script that accepts typed input at runtime and responds dynamically with personalised output.
  • A file reporter that takes a filename as an argument and returns an instant size, line count, and word count report, with graceful error handling for missing files or bad arguments.
  • Secret Mission: Build a colour-coded system health check script that reports disk usage, memory, and top processes.

Are there any prerequisites?

You only need basic familiarity with typing commands in a terminal (cd, ls, mkdir). No prior scripting experience is required.

Before We Start

Before we dive in, let's lock in what you're about to build and why it matters.

You're about to write your first Bash scripts from scratch. By the end, you'll have a collection of working scripts that accept input, pull live system data, and handle errors gracefully. This is the foundation for automating real tasks like backups, monitoring, and deployments.

Set Up Your Scripting Environment

Every script you write in this project needs three things to run: a Linux shell to interpret it, a text editor to write it, and version control to track your changes.

In this step, you will install WSL2 (Windows Subsystem for Linux) to get a full Ubuntu terminal on your Windows machine, set up Git for version control, and create the project folder where all your scripts will live.

In this step, get ready to:
  • Install WSL2 with Ubuntu and verify Bash is working.
  • Install and configure Git with your identity.
  • Create and initialise a Git repository for your scripts.
Install WSL2 with Ubuntu

WSL2 lets you run a real Linux environment directly inside Windows. This gives you access to Bash, the shell interpreter that will run every script in this project.

  • Press the Windows key to open your search bar.
  • Type PowerShell.
  • Right-click Windows PowerShell and select Run as administrator.
  • Install WSL2 by running this command:
wsl --install

What does this command do?

This single command enables the WSL2 feature, downloads Ubuntu as the default Linux distribution, and sets everything up.

After it finishes, you will need to restart your machine for the changes to take effect.

  • When the command completes, restart your computer.
  • After restarting, Ubuntu will launch automatically and ask you to create a Linux username and password.
  • Enter a username and password when prompted. This is your Linux account and is separate from your Windows login.

Already have WSL installed?

If running wsl --install shows WSL help text instead of starting an installation, WSL is already set up on your machine.

Press the Windows key, type Ubuntu, and press Enter to open your existing Ubuntu terminal.

  • Check your Bash version by running this command:
bash --version

What do you think you will see? Before reading on, predict what the output might contain.

You should see output starting with GNU bash, version 5.2 (or a similar version number).

✔️ I see version 5.2 or higher

Your Bash shell is ready. Move on to the next substep.

ⓧ I see an older version

An older Bash version means your Ubuntu distribution is outdated. Update it by running:

sudo apt-get update && sudo apt-get upgrade -y

After the upgrade finishes, run bash --version again to confirm you now see 5.2 or higher.

ⓧ Command not found or nothing happened

Make sure you are inside the Ubuntu terminal, not PowerShell or Command Prompt.

  • Press the Windows key, type Ubuntu, and press Enter.
  • If Ubuntu does not appear, try restarting your machine again. The WSL installation requires a reboot to complete.
  • Once inside Ubuntu, run bash --version again.
Install Git and configure it

Git tracks every change you make to your scripts so you can see your progress and roll back mistakes.

  • Install the latest Git by running this command:
sudo apt-get update && sudo apt-get install -y git

What does this command do?

The first part (sudo apt-get update) refreshes the list of available packages so Ubuntu knows what is current.

The second part (sudo apt-get install -y git) installs Git. The -y flag automatically confirms the installation so you do not have to type "yes" manually.

  • Verify Git installed correctly by running:
git --version

You should see a version number like git version 2.43 or higher.

Permission denied when running sudo?

If you see a permission error, make sure you are typing the password you created when Ubuntu first launched. The password will not show any characters as you type. This is normal Linux behaviour.

Help me fix a permission denied error with sudo in WSL

Now configure Git with your name and email so your commits are labelled correctly.

  • Set your Git username by running this command (replace Your Name with your actual name):
git config --global user.name "Your Name"
  • Set your Git email by running this command (replace you@example.com with your actual email):
git config --global user.email "you@example.com"

Why does Git need my name and email?

Every Git commit records who made the change. This identity is stored locally on your machine and only appears in your commit history.

Create the project directory and initialise a Git repository

All your scripts will live in a single folder tracked by Git. This keeps everything organised and version-controlled from the start.

  • Create the project folder and move into it by running these commands:
mkdir ~/bash-scripts && cd ~/bash-scripts
  • Initialise the folder as a Git repository by running:
git init

What does git init do?

This command creates a hidden .git folder inside ~/bash-scripts. That folder is where Git stores your project history. From now on, anything you commit in this directory is tracked.

Before you verify, predict what you expect to see. What should pwd print? What should git status say about a brand-new repository?

  • Confirm your current directory by running:
pwd

You should see /home/youruser/bash-scripts (where youruser is the Linux username you created earlier).

  • Check the Git status by running:
git status

You should see a message saying you are on the main (or master) branch with nothing to commit.

Seeing 'not a git repository'?

This means git init did not run in the right folder. Run cd ~/bash-scripts first, then run git init again. After that, git status should work.

Help me fix a 'not a git repository' error in WSL

Your scripting environment is ready. Next up, you will write your first Bash script and run it from the terminal.

Write and Run Your First Script

Your scripting environment is set up and ready to go. Now it's time to write something that actually runs in the terminal.

In this step, you'll create a simple script, try to execute it, and run headfirst into one of the most common beginner hurdles in Linux. Fixing that hurdle teaches you a foundational concept about how Linux handles file permissions.

In this step, get ready to:
  • Create your first Bash script using the nano editor.
  • Fix the Permission denied error every beginner encounters.
  • Commit your working script to Git.
Create hello.sh with nano

A Bash script is a plain text file containing commands that the shell executes line by line. The very first line tells Linux which program should interpret the file.

  • In your terminal, open the nano text editor to create a new file called hello.sh by running this command:
nano hello.sh

What will you see?

Nano opens a blank editor inside your terminal. You'll see a cursor at the top and a command bar at the bottom showing shortcuts like ^O Write Out and ^X Exit. The ^ symbol means Ctrl.

  • Type the following script into nano:
#!/bin/bash
echo "Hello, World!"
echo "This is my first Bash script."
echo "I am learning Bash for DevOps!"

What does this code do?

#!/bin/bash is the shebang line. It tells Linux to use Bash as the interpreter for this file.

Each echo command prints a line of text to the terminal. When you run the script, these three lines print one after another.

  • Save the file by pressing Ctrl+O, then press Enter to confirm the filename.
  • Exit nano by pressing Ctrl+X.
  • Confirm the file saved correctly by running:
cat hello.sh

You should see all four lines of your script printed back, starting with #!/bin/bash.

See an empty file or nothing at all?

If cat shows an empty file, you likely exited nano without saving. Re-open it with nano hello.sh and make sure to press Ctrl+O then Enter before pressing Ctrl+X.

help me fix my nano save issue

✔️ Awesome, I've got everything!

Great. Double check you've saved your file and move on to running it.

ⓧ I'd like to double check the full code

Your hello.sh should look exactly like this:

#!/bin/bash
echo "Hello, World!"
echo "This is my first Bash script."
echo "I am learning Bash for DevOps!"
Run the script and fix file permissions

To execute a script in the current directory, you prefix it with ./. This tells Bash to look right here instead of searching the system path.

Before you run this, what do you think will happen? Will you see your three echo lines printed to the terminal?

  • Try running your script:
./hello.sh

You see this error instead of your greeting:

bash: ./hello.sh: Permission denied

That's expected. Every beginner hits this wall.

Why Permission denied?

Linux requires explicit execute permission before it will run a file as a script. When you create a new file, it only gets read and write permissions by default.

You need to add execute permission with the chmod command before Linux will treat the file as something it can run.

  • Add execute permission to your script by running:
chmod +x hello.sh
  • Now run your script again:
./hello.sh

This time you should see:

Hello, World!
This is my first Bash script.
I am learning Bash for DevOps!

Still seeing Permission denied?

Make sure you ran chmod +x hello.sh (not chmod x hello.sh). The + is required to add the permission.

Confirm you're in the right directory by running pwd. You should see a path ending in bash-scripts.

help me fix my script permissions

Commit your first script to Git

Your script runs. Time to save this milestone in Git so you have a record of your progress.

  • Stage and commit hello.sh by running these commands:
git add hello.sh
git commit -m "Add first hello world script"

What do these commands do?

git add hello.sh stages the file, telling Git you want to include it in your next snapshot.

git commit -m "..." saves that snapshot with a descriptive message. Think of each commit as a checkpoint you can return to.

How many commits do you expect to see in your Git history right now?

  • Verify your commit exists by running:
git log --oneline

You should see one line showing a short commit hash followed by Add first hello world script.

Don't see a commit?

If you get a "does not have any commits yet" message, you may have forgotten the git add step. Run git status to see whether hello.sh is listed as untracked or staged.

help me fix my git commit

Your first script is running and safely tracked in Git. Next, you'll make your scripts dynamic by adding variables and user input.

Add Variables and User Input

Your first script runs and prints three hardcoded lines. That is a great start, but hardcoded text is useless for automation.

Variables let your scripts store and reuse values. The read command lets scripts accept input at runtime, so they adapt to different situations without you editing the code. In this step, you will create an interactive greeting script that responds to whoever runs it.

In this step, get ready to:
  • Create a script that stores values in variables and prints them.
  • Upgrade the script to accept user input at runtime with read.
  • Commit the interactive script to Git.
Create greeting.sh with variables

A variable in Bash stores a value you can reuse throughout your script. You assign a variable with name=value (no spaces around the equals sign) and reference it later with a $ prefix.

  • Create a new file called greeting.sh by opening it in nano:
nano greeting.sh
  • Type this code to define two variables and print them:
#!/bin/bash
name="World"
echo "Hello, $name!"

greeting="Welcome to Bash scripting"
echo "$greeting, $name!"

What does this code do?

  • name="World" creates a variable called name and stores the text World inside it.
  • greeting="Welcome to Bash scripting" creates a second variable with a longer string.
  • $name and $greeting tell Bash to substitute the stored values when it prints the line.
  • Press Ctrl+O, then Enter to save the file.
  • Press Ctrl+X to exit nano.
  • Make the script executable and run it:
chmod +x greeting.sh
./greeting.sh

You should see two lines of output: Hello, World! and Welcome to Bash scripting, World!.

Why no spaces around the equals sign?

Writing name = "World" (with spaces) is the number one Bash beginner mistake. Bash interprets name as a command name and = as an argument, giving you bash: name: command not found.

Variable assignment in Bash must always be written as variable=value with no spaces on either side.

Not seeing the output?

  • If you see Permission denied, make sure you ran chmod +x greeting.sh before ./greeting.sh.
  • If you see command not found, check for spaces around the = sign in your variable assignments.
  • Confirm #!/bin/bash is the very first line of the file with no blank lines above it.

Help me debug my greeting.sh script that isn't printing variable values

Add user input with read

Variables with hardcoded values are a step forward, but your script still does the same thing every time. The read command pauses the script and waits for the user to type something, storing their response in a variable.

  • Open greeting.sh in nano:
nano greeting.sh
  • Delete all existing lines by pressing Ctrl+K once per line until the file is empty.
  • Type this updated script that replaces the hardcoded name with user input:
#!/bin/bash
echo "Hello, World!"

read -p "What is your name? " user_name
echo "Nice to meet you, $user_name!"

greeting="Welcome to Bash scripting"
echo "$greeting, $user_name!"

What does this code do?

  • read -p "What is your name? " user_name prints the prompt text and waits for the user to type a response. Whatever they type gets stored in the user_name variable.
  • The -p flag lets you combine the prompt and the read into one line, so you do not need a separate echo before it.
  • $user_name is then used in the echo statements below, so the greeting personalises itself for every user.
  • Press Ctrl+O, then Enter to save.
  • Press Ctrl+X to exit nano.
  • Run the updated script:
./greeting.sh

The script prints Hello, World! and then pauses with the prompt What is your name?. Type your name and press Enter. You should see a personalised greeting using the name you typed.

Script not waiting for input?

  • Check that the -p flag is directly after read with a space between them: read -p.
  • Ensure the prompt string is in double quotes and there is a space before the closing quote so the cursor does not bump against the prompt text.
  • If the script runs the old version, confirm you saved with Ctrl+O before exiting nano.

Help me fix my read command in greeting.sh

✔️ Awesome, I've got everything!

Great. Double check you have saved greeting.sh and confirmed the personalised greeting works.

ⓧ I'd like to double check the full code

Your greeting.sh should look exactly like this:

#!/bin/bash
echo "Hello, World!"

read -p "What is your name? " user_name
echo "Nice to meet you, $user_name!"

greeting="Welcome to Bash scripting"
echo "$greeting, $user_name!"
Commit and verify
  • Stage and commit greeting.sh to Git by running:
git add greeting.sh
git commit -m "Add interactive greeting script with variables and read"

Before you run the script one final time, predict what you will see. Will the script print the same greeting as before, or will it ask for your name again?

  • Run the script and enter a name with spaces (for example, Jane Doe) to confirm quoting handles it correctly:
./greeting.sh

The script prompts for your name, and when you type Jane Doe you should see the full name printed back in both greeting lines with no truncation.

  • Confirm your commit history by running:
git log --oneline

You should see your new commit with the message Add interactive greeting script with variables and read at the top of the log.

Commit not showing up?

  • If git status shows greeting.sh as untracked, you may have skipped git add greeting.sh. Run both the add and commit commands again.
  • If you see a message about identity not being set, run git config --global user.name and git config --global user.email with your details from Step 1.

Help me fix my Git commit for greeting.sh

Your scripts now respond to whoever runs them. Next up, you will capture live system data and accept filenames as arguments, so your scripts can report on real files without any interactive prompts.

Use Command Substitution and Script Arguments

Your greeting script uses read to gather input interactively. That works when a human is sitting at the keyboard, but real automation scripts run unattended.

In this step, you will use command substitution to capture live system data (dates, usernames, directory paths) and positional parameters to accept different inputs each time the script runs. No human prompts needed.

In this step, get ready to:
  • Create a file information script that captures system data automatically.
  • Run the script with different file arguments to generate reports.
  • Discover what happens when the script receives bad input.
Create fileinfo.sh with command substitution

Command substitution uses the $() syntax to run a command and capture its output into a variable. Instead of asking the user to type their name, the script can just ask the system directly.

  • Create a new file called fileinfo.sh by running:
nano fileinfo.sh
  • Type the following code into the editor:
#!/bin/bash
current_date=$(date)
current_user=$(whoami)
current_dir=$(pwd)

echo "=== File Information Report ==="
echo "Report generated: $current_date"
echo "Generated by: $current_user"
echo "Working directory: $current_dir"
echo ""

filename=$1
echo "File requested: $filename"
echo "File size: $(wc -c < "$filename") bytes"
echo "Line count: $(wc -l < "$filename") lines"
echo "Word count: $(wc -w < "$filename") words"

What does this code do?

This script has three sections working together:

  • Lines 2-4 use command substitution $() to run date, whoami, and pwd and store their output in variables. The command runs first, then its output becomes the variable's value.
  • Lines 6-10 print a report header using those stored variables.
  • Line 12 uses $1 to grab the first argument passed to the script when it was run. Lines 13-16 use inline command substitution to calculate file stats on the spot.

Why use input redirection with wc?

The < "$filename" syntax feeds the file contents into wc as input. This makes wc print only the number, without repeating the filename. Cleaner output for your report.

  • Save the file by pressing Ctrl+O, then Enter.
  • Exit nano by pressing Ctrl+X.
  • Make the script executable by running:
chmod +x fileinfo.sh
  • Run the script, passing hello.sh as the argument:
./fileinfo.sh hello.sh

You should see a report showing today's date, your username, the current directory, and the byte/line/word counts for hello.sh.

Not seeing the report?

  • If you see a permission error, confirm you ran chmod +x fileinfo.sh before executing it.
  • If the counts show 0 or an error, make sure you typed hello.sh (not the path to a different file) and that you are inside ~/bash-scripts.

Help me debug my fileinfo.sh output.

Run the script with a nonexistent file

Your script works perfectly with a real file. But what happens when someone passes a filename that does not exist?

  • Before you run the next command, predict what you think will happen. Will the script handle it gracefully, or will something break?
  • Run the script with a file that does not exist:
./fileinfo.sh nonexistent.txt

The script crashes with error messages about missing files. The report header prints fine (those lines use stored variables), but every wc line fails because it tries to read a file that is not there.

Why does this crash matter?

This is not a bug in your code. It is a missing feature. The script has no way to check whether the file exists before trying to read it. In a real automation workflow, bad input is inevitable.

You will fix this in the next step by adding conditional logic that validates the input before processing.

Commit the script to Git
  • Add and commit your new script by running:
git add fileinfo.sh
git commit -m "Add file info reporter with command substitution and arguments"
  • Before running the next command, predict how many commits you expect to see in the log.
  • Verify your work by running:
./fileinfo.sh greeting.sh

This time the report shows the stats for greeting.sh instead of hello.sh. The $1 parameter changes the target file based on whatever argument you pass.

  • Confirm your commit history by running:
git log --oneline

You should see three commits: your original hello world script, the greeting script, and the new file info reporter.

Only seeing one or two commits?

  • Run git status to check if fileinfo.sh is still in the staging area or untracked.
  • If you see the file as untracked, run the git add and git commit commands above again.

Help me figure out why my Git commit is missing.

✔️ Awesome, I've got everything!

Great. Double check you have saved fileinfo.sh and that your git log shows three commits.

ⓧ I'd like to double check the full code

Here is the complete fileinfo.sh for comparison:

#!/bin/bash
current_date=$(date)
current_user=$(whoami)
current_dir=$(pwd)

echo "=== File Information Report ==="
echo "Report generated: $current_date"
echo "Generated by: $current_user"
echo "Working directory: $current_dir"
echo ""

filename=$1
echo "File requested: $filename"
echo "File size: $(wc -c < "$filename") bytes"
echo "Line count: $(wc -l < "$filename") lines"
echo "Word count: $(wc -w < "$filename") words"

Your script pulls live system data and generates reports on any file you point it at. One problem remains: it crashes hard on bad input. Next up, you will add conditional logic to handle those edge cases gracefully.

Add Conditionals to Validate Input

In the previous step, you built fileinfo.sh to generate file reports using command substitution and arguments. It works perfectly when you give it a real file. But when you pass a nonexistent filename, it crashes with ugly errors.

Conditionals let your script check conditions before acting. In this step, you will build a new script that validates its inputs and responds gracefully to every scenario instead of crashing.

In this step, get ready to:
  • Create filecheck.sh with argument validation and file-testing logic.
  • Test all four conditional branches to confirm each one works.
  • Commit the final script to Git.
Create filecheck.sh with argument validation

Bash provides if/elif/else blocks that let your script choose different paths based on conditions. You will use these to check whether the user provided an argument, whether that argument is a file, a directory, or something that does not exist.

  • Open a new file in nano by running this command:
nano filecheck.sh
  • Type the header and argument validation section of the script:
#!/bin/bash
current_date=$(date)
current_user=$(whoami)

echo "=== File Checker Report ==="
echo "Report generated: $current_date"
echo "Generated by: $current_user"
echo ""

if [ $# -eq 0 ]; then
    echo "Error: No filename provided."
    echo "Usage: $0 <filename>"
    exit 1
fi

filename=$1

What does this code do?

  • The shebang line #!/bin/bash tells the system to use Bash as the interpreter.
  • current_date=$(date) and current_user=$(whoami) capture live system data into variables using command substitution.
  • if [ $# -eq 0 ] checks whether the user passed zero arguments. If so, it prints a usage message with $0 (the script name) and exits with code 1 to signal an error.
  • filename=$1 stores the first argument for use in the next section.
  • Continue typing directly below the previous code, adding the file-checking logic:
if [ -f "$filename" ]; then
    echo "File '$filename' exists and is a regular file."
    echo "File size: $(wc -c < "$filename") bytes"
    echo "Line count: $(wc -l < "$filename") lines"
    echo "Word count: $(wc -w < "$filename") words"
elif [ -d "$filename" ]; then
    echo "'$filename' is a directory, not a file."
    echo "Contents:"
    ls "$filename"
else
    echo "Error: '$filename' does not exist."
    echo "Please check the path and try again."
    exit 1
fi

echo ""
echo "=== Report Complete ==="

What does this code do?

  • [ -f "$filename" ] tests whether the path is a regular file. If true, it prints the file stats using wc.
  • [ -d "$filename" ] tests whether the path is a directory. If true, it lists the directory contents with ls.
  • The else branch catches anything that is neither a file nor a directory. It prints an error and exits.
  • The final echo lines print a closing banner so you know the report finished cleanly.
  • Save the file by pressing Ctrl+O, then Enter.
  • Exit nano by pressing Ctrl+X.

✔️ Awesome, I've got everything!

Great. Make sure you have saved and exited nano before continuing.

ⓧ I'd like to double check the full code

Since the file has two sections, scroll up and confirm both are present in order:

  • The header and argument validation section (starting with #!/bin/bash and ending with filename=$1).
  • The file-checking logic section (starting with if [ -f "$filename" ]; then and ending with echo "=== Report Complete ===").

If anything looks off, reopen the file with nano filecheck.sh and fix it.

Test all three conditional branches

Your script has four possible paths: no argument, existing file, directory, and nonexistent path. You will trigger each one to confirm the logic works.

  • Make the script executable by running:
chmod +x filecheck.sh

Before running the tests, predict what you think each command will print. Will the script crash like fileinfo.sh did, or handle each case gracefully?

  • Test with no argument by running:
./filecheck.sh

You see the report header, then an error message saying no filename was provided, followed by a usage hint showing the script name.

  • Test with an existing file by running:
./filecheck.sh hello.sh

You see the report header, confirmation that the file exists, and its size, line count, and word count.

  • Test with a directory by running:
./filecheck.sh ~/bash-scripts

You see a message saying it is a directory, followed by a listing of its contents.

  • Test with a nonexistent path by running:
./filecheck.sh nonexistent.txt

You see an error message saying the file does not exist, with a suggestion to check the path. No crash, no ugly system errors.

Why is this better than fileinfo.sh?

When you ran ./fileinfo.sh nonexistent.txt in the previous step, wc threw raw system errors because the script blindly tried to read a file that did not exist. Your new script checks first, then acts. This is called defensive scripting, and it is how production scripts avoid breaking unexpectedly.

Seeing a syntax error?

  • Check that every if statement has a matching fi. Your script should have two fi lines total.
  • Make sure there are spaces inside the square brackets: [ $# -eq 0 ] not [$# -eq 0]. Bash requires these spaces.
  • Confirm the then keyword is on the same line as if, separated by a semicolon: if [ ... ]; then.

Fix the script with nano filecheck.sh. help me debug a syntax error in my Bash if/elif/else script

Commit the final script
  • Add and commit filecheck.sh to Git by running these commands:
git add filecheck.sh
git commit -m "Add file checker with conditional validation"

What do you expect to see when you check your Git history? How many commits should there be?

  • Verify your full commit history by running:
git log --oneline

You see four commits listed, one for each script you have built across this project.

Don't see four commits?

  • If you see only three, make sure you ran both git add and git commit for filecheck.sh. Running git status will show whether the file is staged or untracked.
  • If you see a message about an empty commit, check that filecheck.sh exists in your ~/bash-scripts directory with ls.

help me fix my Git commit history for my Bash scripts project

Your scripts can now handle unexpected input without crashing. Next up, you will take on the Secret Mission and combine everything you have learned into a colour-coded system health checker.

Secret mission

Build a System Health Check Script

You have all the building blocks. Variables, command substitution, arguments, conditionals. Now combine them into a single script that monitors your system's health and reports back with colour-coded warnings. This is the kind of script DevOps engineers run on real servers every day.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely on your local machine inside WSL, so there are no ongoing costs or cloud resources to worry about. Decide whether to keep your scripts for future reference, or delete them to free up space.

Resources you used:

  • ~/bash-scripts directory containing all scripts and a Git repository.
  • Git installed inside WSL via apt-get.
  • WSL2 with Ubuntu distribution.

Keep everything running

No action needed. Choose this if you plan to keep learning Bash or use these scripts as reference material for future projects.

  • Your scripts stay in ~/bash-scripts and are ready to run any time you open Ubuntu.
  • The entire project takes up less than 1 MB of disk space.
  • WSL2 and Git remain available for other projects.

Pause - I'll come back to this later

There are no running processes or servers to stop. Your scripts are just files on disk, so pausing simply means closing the terminal.

  • Close your Ubuntu terminal window.
  • Your files persist in ~/bash-scripts and will be there next time you open Ubuntu.

Delete - I don't want to use this again

Remove all project files and optionally uninstall the tools. Only remove WSL2 if you have no other use for a Linux environment on your machine.

  • Delete the project directory by running this in your Ubuntu terminal:
  • Remove the entire ~/bash-scripts folder and its Git history.
rm -rf ~/bash-scripts
  • Confirm the folder is gone by running:
ls ~/bash-scripts

You should see No such file or directory.

  • Remove Git from WSL by running:
sudo apt-get remove -y git
  • If you want to remove WSL2 entirely, open PowerShell as Administrator on Windows and run:
wsl --unregister Ubuntu

Removing WSL is permanent

Running wsl --unregister Ubuntu permanently deletes the entire Ubuntu distribution and all files inside it. Only do this if you are certain you do not need WSL for anything else.

Nice Work!

Nice Work!

You just built a collection of working Bash scripts from scratch, starting with a simple greeting and finishing with a defensive file-checking tool that validates inputs before processing.

You've learned how to:

  • Write and execute Bash scripts with proper shebang lines, file permissions (chmod +x), and Git version control.
  • Build interactive scripts using variables, user input with read, command substitution $(), and positional parameters like $1 and $#.
  • Add defensive input validation with if/elif/else conditionals and file test operators (-f, -d) so scripts handle errors gracefully instead of crashing.
  • Secret Mission: Built a colour-coded system health checker that monitors disk usage, memory, and top processes.

Ready to quiz yourself?