Linux Health Check for Support Engineers

Build a Bash health check script that monitors disk, memory, CPU, and services.

Introduction

30 Second Summary

When a server goes down or runs slow, the first person called is a platform support engineer. Their first move is always a system health check.

In this project, you will set up a Linux environment on your Windows machine and build a real health check script that monitors disk usage, memory, CPU load, services, and logs automatically.

What You'll Build

A Bash health check script that mirrors the daily diagnostic routines of production support engineers working on platforms like HPE GreenLake.

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

  • A configured Ubuntu Linux environment running on your Windows machine via WSL.
  • Hands-on experience with 20+ essential sysadmin commands for filesystem navigation, resource monitoring, service management, and log analysis.
  • A working health check script (health-check.sh) that outputs a formatted system report.
  • Secret Mission: Add network diagnostics and automate the script with cron scheduling.

Are there any prerequisites?

You just need a Windows 10 or 11 PC. This guide walks you through every installation step from scratch, including setting up your Linux environment.

Install WSL and Ubuntu

To build a real health check script, you need a Linux environment to work in. Most production servers run Linux, so getting comfortable with a Linux terminal is the first skill an L2/L3 support engineer needs.

In this step, you will install Windows Subsystem for Linux (WSL) on your Windows machine. WSL gives you a full Ubuntu Linux environment running directly on Windows, no virtual machine software required.

In this step, get ready to:
  • Install WSL 2 and Ubuntu on your Windows machine.
  • Create your Linux username and password.
  • Update your system packages and verify everything works.
Open PowerShell and install WSL

WSL 2 runs a real Linux kernel on your Windows machine. A single PowerShell command handles the entire installation: enabling WSL, downloading the Linux kernel, setting WSL 2 as the default, and installing Ubuntu.

  • Press the Windows key to open your search bar.
  • Type PowerShell and look for Windows PowerShell in the results.
  • Right-click Windows PowerShell and select Run as administrator.
  • If a User Account Control prompt appears, click Yes to allow it.

Why run as administrator?

WSL installs system-level components (a Linux kernel, virtual machine features) that require elevated permissions. Running PowerShell as administrator gives the installer permission to make these changes.

  • Check whether WSL is already on your machine by running this command:
wsl --version

✔️ I see version numbers

WSL is already installed on your machine. You still need Ubuntu as your Linux distribution.

  • Install Ubuntu by running this command:
wsl --install -d Ubuntu

If you see a message that Ubuntu is already installed, you are all set. Skip ahead to the "Set up your Ubuntu user account" substep below.

ⓧ I see help text instead of version numbers

WSL exists on your system but is not fully installed. The help text means WSL recognizes the command but has no kernel or distribution set up.

  • Run the full install command:
wsl --install
  • Restart your machine when prompted.

After restarting, continue with the next substep.

ⓧ Command not recognized

WSL is not installed yet. This is expected for a fresh Windows machine.

  • Install WSL and Ubuntu together by running this command:
wsl --install

What does this command do?

  • Enables the WSL and Virtual Machine Platform components on Windows.
  • Downloads and installs the latest Linux kernel.
  • Sets WSL 2 as the default version.
  • Downloads and installs the Ubuntu Linux distribution.
  • Restart your machine when prompted. The installation requires a reboot to finish enabling the new components.

After restarting, continue with the next substep.

Seeing an error during installation?

  • Make sure you are running PowerShell as administrator. Right-click the PowerShell icon and select Run as administrator.
  • Confirm your Windows version is at least Windows 10 version 2004 (Build 19041) or Windows 11. Press Windows + R, type winver, and press Enter to check.

Help me troubleshoot my WSL installation error

Set up your Ubuntu user account

After your machine restarts, Ubuntu opens automatically and asks you to create a user account. This account is separate from your Windows login and becomes your default Linux user.

  • If Ubuntu did not open automatically, press the Windows key, type Ubuntu, and press Enter to launch it.
  • Wait for Ubuntu to finish decompressing its files. You will see a message asking you to create a username.
  • Type a username (lowercase, no spaces) and press Enter.
  • Type a password and press Enter. The characters will not appear as you type. This is normal Linux security behavior.
  • Re-type the password to confirm and press Enter.

Why can't I see my password?

Linux terminals hide password characters to prevent shoulder-surfing. Even though nothing appears on screen, your keystrokes are being recorded. Type carefully and press Enter.

After confirming your password, you will see a command prompt ending in $. This means Ubuntu is ready for commands.

  • Update your system packages by running this command:
sudo apt update && sudo apt upgrade -y

What does this command do?

  • `sudo` runs the command with administrator (root) privileges.
  • `apt update` refreshes the list of available software packages.
  • `apt upgrade -y` installs all available updates, with -y automatically confirming each update.
  • The && means "run the second command only if the first one succeeds."
  • When prompted for a password, type the password you just created and press Enter.

The update process may take a minute or two. You will see packages downloading and installing. When it finishes, you will be back at the $ prompt.

Update command failed?

  • Make sure you typed the password you created during Ubuntu setup, not your Windows password.
  • If you see a network error, check your internet connection and try running the command again.

Help me fix my apt update error in Ubuntu on WSL

Verify your environment is working

Before moving on, confirm that Ubuntu is set up correctly by running three quick checks.

  • Check your Ubuntu version by running:
lsb_release -a
  • You should see Ubuntu listed under Description with a version number.
  • Check your username by running:
whoami
  • You should see the username you chose during setup.
  • Check your current directory by running:
pwd
  • You should see /home/yourusername (with your actual username).

What do these commands tell you?

  • `lsb_release -a` confirms you are running Ubuntu and shows which version.
  • `whoami` confirms which user account is active.
  • `pwd` (print working directory) shows your current location in the filesystem. Your home directory is where you will create files throughout this project.

Not seeing the expected output?

  • If lsb_release says command not found, your Ubuntu installation may be incomplete. Close the terminal and reopen Ubuntu from the Start menu.
  • If pwd shows /root instead of /home/yourusername, you are logged in as the root user. Close and reopen Ubuntu. It should log you in as the user you created.

Help me fix my Ubuntu WSL verification issue

Your Linux environment is ready to go. Next up, you will explore the Linux filesystem and learn to create, copy, and manage files like a support engineer.

Navigate the Linux Filesystem and Manage Files

You have a working Linux environment. Now you need to learn how to move around inside it.

Every time a support engineer troubleshoots a system, they navigate to config files, inspect log directories, and manage scripts. In this step, you'll practice the exact filesystem commands that make all of that possible.

In this step, get ready to:
  • Navigate the Linux filesystem using core commands.
  • Create, copy, move, and delete files and directories.
  • Read and modify Linux file permissions.
Learn to move around the filesystem

Linux organizes everything in a tree of directories starting from a single root (/). Knowing how to move around this tree is the first skill you need.

  • In your Ubuntu terminal, check where you are right now by running these commands:
# Print your current location
pwd

# List files in your current directory
ls

# List all files including hidden ones, with details
ls -la

What do these commands do?

pwd stands for "print working directory." It shows you exactly where you are in the filesystem.

ls lists the files and folders in your current location. Adding -la shows hidden files (those starting with a dot) and extra details like permissions and file sizes.

You should see your home directory path (something like /home/yourusername) from pwd, and a list of files from ls.

  • Now explore the top-level Linux directory structure by running:
# Go to the root (top-level) directory
cd /

# See all the top-level directories
ls

# Return to your home directory
cd ~

What is the root directory?

The / directory is the very top of the Linux filesystem tree. Every file and folder on the system lives somewhere below it.

The ~ symbol is a shortcut for your home directory. Running cd ~ always brings you back home no matter where you are.

  • Explore some important directories that support engineers check frequently:
# Configuration files live here
ls /etc

# System logs live here
ls /var/log

# User home directories live here
ls /home

Why do these directories matter?

/etc holds configuration files for services and the system. When something is misconfigured, this is where you look.

/var/log stores system logs. Your health check script will read from here later.

/home contains a folder for each user on the system. Your personal files, scripts, and configurations live in your home folder.

Create and manage files and directories

Support engineers constantly create log files, move scripts into place, and clean up old data. These file management commands are the building blocks for all of that work.

  • Create a practice directory and some files by running these commands:
# Create a new directory
mkdir ~/practice

# Move into it
cd ~/practice

# Create two empty files
touch file1.txt file2.txt

# Write text into file1.txt
echo "Hello Linux" > file1.txt

# Read the file to confirm
cat file1.txt

What does this code do?

mkdir creates a new directory. touch creates empty files.

echo "Hello Linux" > file1.txt writes the text into the file. The > symbol redirects output into a file, replacing anything that was there before.

cat prints the contents of a file to your screen so you can verify what's inside.

  • Confirm your files exist by running:
ls

You should see file1.txt and file2.txt listed in the output. The cat command above should have printed Hello Linux.

Don't see your files?

Make sure you ran cd ~/practice before running ls. If you're in a different directory, the files won't appear.

Run pwd to check your current location. It should show something like /home/yourusername/practice.

Help me find my files in Linux.

  • Practice copying, moving, and deleting files by running:
# Copy file1.txt to a new file called file3.txt
cp file1.txt file3.txt

# Rename file3.txt to renamed.txt
mv file3.txt renamed.txt

# Delete renamed.txt
rm renamed.txt

# Verify the result
ls

What do these commands do?

cp copies a file. mv moves or renames a file. rm permanently deletes a file.

There is no recycle bin in Linux. Once you rm a file, it's gone. Always double-check what you're deleting.

After running ls, you should see file1.txt and file2.txt remaining. The renamed.txt file is gone because you deleted it.

Understand file permissions

Every file in Linux has permissions that control who can read, write, or execute it. When a service fails because of an access issue, permissions are the first thing a support engineer checks.

  • View the detailed file listing to see permissions by running:
ls -la

Look at the first column of the output. You'll see strings like -rw-r--r--. This is the permission string.

How do permission strings work?

The permission string has 10 characters. The first character indicates the type (- for file, d for directory). The remaining 9 characters are three groups of three.

Each group represents: owner, group, others. Each position is either r (read), w (write), x (execute), or - (no permission).

For example, -rw-r--r-- means the owner can read and write, but everyone else can only read.

  • Change the permissions on file1.txt by running:
# Give full permissions to owner, read+execute to group and others
chmod 755 file1.txt

# Verify the permission change
ls -la file1.txt

What does 755 mean?

Each digit represents permissions for owner, group, and others. The numbers are: 4=read, 2=write, 1=execute. Add them together for each group.

So 7 (4+2+1) = read+write+execute for the owner. 5 (4+1) = read+execute for group and others. The permission string now shows -rwxr-xr-x.

You will use chmod later when you make your health check script executable.

After running ls -la file1.txt, you should see -rwxr-xr-x at the start of the line. This confirms the permission change worked.

Permissions didn't change?

Make sure you're still inside the ~/practice directory. Run pwd to confirm.

If you see "No such file or directory," run cd ~/practice first and then try the chmod command again.

Help me fix my file permissions.

You can now navigate the filesystem, create and manage files, and control who can access them. Next up, you'll use these skills to monitor what's actually happening on the system.

Monitor System Resources and Processes

You can now navigate the Linux filesystem, create files, and read permissions. These are essential building blocks.

The next skill every support engineer needs is answering the question: "Why is this system slow?" In this step, you will run the exact commands that L2/L3 engineers use to diagnose disk pressure, memory exhaustion, and runaway processes.

In this step, get ready to:
  • Check disk space, memory usage, and CPU load with three core commands.
  • Inspect running processes and filter them by name.
  • Identify the top resource-consuming processes on your system.
Check disk, memory, and CPU

When a system is reported as slow or unresponsive, the first three commands any support engineer runs are df -h, free -h, and uptime. These give you an instant snapshot of your system's health.

  • Check your disk usage by running this command:
df -h

What does this command do?

The df command reports disk space usage for each mounted filesystem. The -h flag makes the output human-readable (GB and MB instead of raw bytes).

Look for the %Use column. If any filesystem is above 90%, the system may start behaving unpredictably.

  • Check your memory (RAM) usage by running:
free -h

What does this command do?

The free -h command displays how much RAM and swap space is in use, available, and free. The row labeled Mem: shows physical memory. The Swap: row shows disk-based overflow memory.

  • Check your system uptime and CPU load averages by running:
uptime

What does this command do?

The uptime command shows how long the system has been running and three load average numbers. These numbers represent CPU pressure over the last 1 minute, 5 minutes, and 15 minutes.

If the load averages are consistently higher than the number of CPU cores, the system is overloaded. On a single-core machine, a load average above 1.0 means processes are waiting in line for CPU time.

You should see numerical output for each command. The df -h output shows a table of filesystems, free -h shows memory rows, and uptime shows a single line with time and load values.

Inspect running processes

Knowing disk and memory usage tells you what is strained. Process inspection tells you who is causing the strain. The next set of commands shows you every running process and how to filter them.

  • View a snapshot of all running processes by running:
ps aux

This produces a lot of output. Each line is one process. The key columns to read are USER (who owns it), PID (process ID), %CPU, %MEM, and COMMAND (what program is running).

  • Limit the output to just the first 20 lines by running:
ps aux | head -20

What is the pipe symbol?

The pipe (|) sends the output of one command into another command as input. Here, ps aux generates a long list and head -20 keeps only the first 20 lines. Pipes are essential for filtering data during incident troubleshooting.

  • Get a one-shot view of the top processes sorted by resource usage by running:
top -b -n1 | head -15

What does this command do?

The -b flag runs top in batch mode (plain text output instead of the interactive screen). The -n1 flag tells it to capture exactly one snapshot and then exit. Piping into head -15 gives you just the summary and first few processes.

  • Filter for a specific process by name. Search for any SSH-related processes by running:
ps aux | grep ssh

You should see at least one line containing grep ssh in the output. That is the grep command itself showing up in the process list. If SSH is running, you will see additional lines.

Why is filtering processes useful?

During an incident, you often need to check whether a specific service is still running. Instead of scrolling through hundreds of process lines, ps aux | grep <name> instantly isolates the one you care about.

Explore the top command interactively

The top command also has a live, interactive mode. This is what engineers keep open on a second monitor during an active incident to watch resource usage change in real time.

  • Launch the interactive process monitor by running:
top

Your terminal now shows a live-updating display of all processes, sorted by CPU usage by default.

  • Press M (capital M) to sort processes by memory usage.
  • Press P (capital P) to sort back to CPU usage.
  • Press q to quit and return to your normal terminal.

When would I use interactive top?

In a real support scenario, you would use interactive top to watch a misbehaving process in real time. If you see a process climbing from 30% CPU to 90% over a few seconds, you have found your culprit.

For scripting and reports, the batch mode version is more useful because its output can be captured to a file. Try this cleaner format for getting the top 5 CPU-consuming processes.

  • Get a clean list of the top 5 CPU-consuming processes by running:
ps -eo user,pid,%cpu,%mem,command --sort=-%cpu | head -6

What does this command do?

The -eo flag tells ps to output only the columns you specify: user, pid, %cpu, %mem, and command. The --sort=-%cpu flag sorts by CPU usage descending (highest first).

The head -6 keeps the header row plus 5 process rows. This gives you a clean, readable answer to "what is eating my CPU?" in one command.

You should see a neat table with 6 rows. The first row is the column header (USER, PID, %CPU, %MEM, COMMAND) and the remaining rows show your top processes.

Not seeing any output or getting an error?

Make sure you copied the command exactly, including the --sort=-%cpu part with the double dash and minus sign. A missing dash changes the sort direction.

If top seemed frozen, you may still be inside it. Press q to exit back to your normal terminal prompt before running the next command.

Help me troubleshoot why my process commands aren't showing output in WSL.

You can now diagnose system health in seconds using the same commands production engineers rely on. Next up, you will learn how to manage services and dig into system logs to find the root cause of problems.

Manage Services and Analyze Logs

In the previous step, you learned how to monitor system resources and track down resource-hungry processes. Now you need to go deeper.

When a system is slow or unresponsive, knowing the CPU and memory usage is only half the story. You also need to check whether critical services are running and inspect system logs for errors. This step covers the "service monitoring" and "analyze logs, identify root cause" skills that production support engineers use every day.

In this step, get ready to:
  • Manage services with systemctl (start, stop, restart, check status).
  • Filter and search system logs with journalctl.
  • Explore traditional log files in /var/log/ for kernel and system messages.
Work with systemd services

Linux uses a system called systemd to manage background services (like web servers, databases, and SSH daemons). The command systemctl is how you interact with these services.

  • See all currently running services by running this command:
systemctl list-units --type=service --state=running

You should see a table listing active services on your system. Each row shows the service name, its load state, active state, and a short description.

  • Check the status of a specific service by running:
systemctl status ssh

What is SSH?

SSH (Secure Shell) is a protocol for securely connecting to remote machines. On a fresh WSL install, the SSH service is typically inactive because nobody has started it yet. That is expected.

  • Check for any failed services by running:
systemctl --failed

If no services have failed, you will see an empty list. On a production server, failed services here would be your first clue that something needs attention.

  • Practice the full service lifecycle by starting, stopping, and restarting the SSH service:
sudo systemctl start ssh
systemctl status ssh
sudo systemctl stop ssh
systemctl status ssh
sudo systemctl restart ssh
systemctl status ssh

What does this sequence do?

You are running the same three operations that support engineers use daily to manage services.

  • sudo systemctl start ssh starts the SSH service. You need sudo because managing services requires administrator privileges.
  • sudo systemctl stop ssh shuts the service down gracefully.
  • sudo systemctl restart ssh stops and immediately starts the service again. This is the most common fix for a misbehaving service.

After the final systemctl status ssh, you should see the SSH service listed as active (running).

Seeing "System has not been booted with systemd"?

This error means systemd is not enabled in your WSL instance. The current Ubuntu version installed via wsl --install should have systemd enabled by default. If you see this error, open PowerShell and run wsl --shutdown, then reopen Ubuntu. If that does not fix it, check that your /etc/wsl.conf file contains [boot] with systemd=true below it.

Help me fix my systemctl commands in WSL

Read and filter system logs with journalctl

When something goes wrong on a Linux system, logs tell you exactly what happened and when. The journalctl command gives you access to all logs managed by systemd's journal.

  • View all logs from the current boot by running:
journalctl -b

This produces a lot of output. Press q to exit the log viewer when you are done scrolling.

  • Filter for only error-level messages and above by running:
journalctl -b -p 3

What are priority levels?

The -p 3 flag filters by priority. Journalctl uses standard syslog priority levels: 0=emergency, 1=alert, 2=critical, 3=error, 4=warning, 5=notice, 6=info, 7=debug.

Using -p 3 shows errors and anything more severe (levels 0-3). This is how support engineers quickly find what went wrong without wading through thousands of informational messages.

  • Get just the last 20 error messages in a clean format by running:
journalctl -b -p 3 --no-pager | tail -20

What does this command do?

  • --no-pager outputs everything at once instead of opening the interactive viewer.
  • | tail -20 takes only the last 20 lines. The pipe (|) sends the output of one command into another.
  • Filter logs by time window by running:
journalctl --since "10 min ago"

This shows only log entries from the last 10 minutes. During an incident, you would set this to the time the problem was first reported.

  • View logs for a specific service by running:
journalctl -u ssh -n 20

What does this command do?

  • -u ssh filters logs to show only entries from the SSH service.
  • -n 20 limits the output to the 20 most recent entries. This is how you investigate why a specific service crashed or failed to start.

You should see log entries showing the SSH service starting, listening on port 22, and any related events.

Explore traditional log files

Not all logs are managed by journalctl. Linux also stores traditional log files in the /var/log/ directory. Knowing both methods gives you full coverage for troubleshooting.

  • See what log files are available by running:
ls /var/log/

You should see files like syslog, auth.log, kern.log, and others. Each file captures a different category of system events.

  • Read the last 20 lines of the system log by running:
cat /var/log/syslog | tail -20
  • View the last 20 kernel messages by running:
sudo dmesg | tail -20

What is dmesg?

The dmesg command shows kernel ring buffer messages. These include hardware events, driver loading, and low-level system information. On a real server, this is where you would look for disk failures, memory errors, or network adapter issues.

Seeing "No such file" for syslog?

On some fresh WSL installs, /var/log/syslog may not exist yet if the rsyslog service is not running. You can skip that command and move on to sudo dmesg | tail -20 which always works. The important takeaway is knowing where these files live and how to read them.

Help me find my system logs in WSL

You now have the full toolkit for service monitoring and log analysis. You can check service health, start and stop services, and dig through logs by priority, time, and service name. Next up, you will combine all of these commands into a single automated health check script.

Build Your Health Check Script

You now know how to check disk space, memory, CPU load, manage services, and filter logs individually. The next step is combining all of these commands into a single automated script.

Support engineers do not type 10+ commands one by one during every shift. They run a Bash script that performs every check in sequence and saves the results to a file. In this step, you will build that script from scratch.

In this step, get ready to:
  • Create a health check script file and make it executable.
  • Write the full script that checks disk, memory, CPU, services, processes, and logs.
  • Run the script and review the saved health report.
Create the script file

Before you can write any code, you need an empty file with execute permissions. This tells Linux that the file is allowed to run as a program.

  • Navigate to your home directory and create the script file by running these commands:
cd ~
touch health-check.sh
chmod +x health-check.sh

What do these commands do?

  • cd ~ moves you back to your home directory (/home/yourusername).
  • touch health-check.sh creates an empty file called health-check.sh.
  • chmod +x health-check.sh adds execute permission so Linux allows you to run it as a script.
  • Confirm the file exists with execute permissions by running:
ls -la health-check.sh
  • You should see -rwxr-xr-x at the start of the line, confirming the file has execute permissions.

Don't see the file?

  • Make sure you ran cd ~ first. If you are still in the ~/practice directory from earlier, touch created the file there instead.
  • Run pwd to check your current location. It should show /home/yourusername.

Help me find where my health-check.sh file was created.

Write the health check script

Now you will write the actual script content. The script combines every monitoring command you practiced in the previous steps into one automated diagnostic.

  • Open the file in the nano text editor by running:
nano health-check.sh

What is nano?

Nano is a beginner-friendly terminal text editor that comes pre-installed on Ubuntu. It shows keyboard shortcuts at the bottom of the screen. You type directly into the file, just like a regular text editor.

  • Type (or paste) the following script into nano:
#!/bin/bash
# Linux System Health Check Script
# Purpose: Perform a daily health check of the Linux system
# Usage: bash ~/health-check.sh

LOGFILE=~/health-report.txt
HOSTNAME=$(hostname)
DATE=$(date '+%Y-%m-%d %H:%M:%S')

{
echo "========================================"
echo " System Health Report"
echo " Host: $HOSTNAME"
echo " Date: $DATE"
echo "========================================"

# Disk Usage
echo ""
echo "[+] Disk Usage:"
df -h

# Memory Usage
echo ""
echo "[+] Memory Usage:"
free -h

# CPU Load
echo ""
echo "[+] CPU Load (1/5/15 min averages):"
uptime

# Failed Services
echo ""
echo "[+] Failed Systemd Services:"
FAILED=$(systemctl --failed --no-legend 2>/dev/null)
if [ -z "$FAILED" ]; then
    echo "  No failed services."
else
    echo "$FAILED"
fi

# Top 5 CPU-Consuming Processes
echo ""
echo "[+] Top 5 CPU Consuming Processes:"
ps -eo user,pid,%cpu,%mem,command --sort=-%cpu | head -6

# Top 5 Memory-Consuming Processes
echo ""
echo "[+] Top 5 Memory Consuming Processes:"
ps -eo user,pid,%cpu,%mem,command --sort=-%mem | head -6

# System Uptime
echo ""
echo "[+] System Uptime:"
uptime -p

# Recent Error Logs
echo ""
echo "[+] Recent Error Logs (Priority 3 and above):"
journalctl -b -p 3 --no-pager 2>/dev/null | tail -10
if [ $? -ne 0 ]; then
    echo "  No error logs available or journalctl not accessible."
fi

echo ""
echo "========================================"
echo " End of Health Report"
echo "========================================"
} | tee "$LOGFILE"

echo ""
echo "Report saved to: $LOGFILE"

What does this script do?

The script groups every health check into a single run. Here is what each section handles:

  • LOGFILE, HOSTNAME, and DATE store where the report saves, the machine name, and the current timestamp.
  • df -h reports disk space, free -h reports memory, and uptime reports CPU load averages.
  • The failed services check uses an if statement to print a friendly message when no services have failed.
  • ps -eo ... --sort=-%cpu | head -6 lists the header row plus the top 5 resource-hungry processes.
  • The entire output is wrapped in { } | tee "$LOGFILE" which prints the report to your screen AND saves it to a file simultaneously.
  • Save the file by pressing Ctrl+O, then press Enter to confirm the filename.
  • Exit nano by pressing Ctrl+X.

Pasting into nano

You can paste the script from your clipboard into the Ubuntu terminal using right-click or Shift+Insert. This is much faster than typing the entire script by hand.

Nano not saving or acting strange?

  • Make sure you press Ctrl+O (the letter O, not zero) to save. The bottom of nano shows ^O Write Out as a hint.
  • If your paste inserted extra blank lines or indentation, delete the file with rm health-check.sh, recreate it with touch health-check.sh && chmod +x health-check.sh, and try pasting again.

Help me fix my health-check.sh script in nano.

✔️ Awesome, I've got everything!

Great. Double check you have saved the file and exited nano before continuing.

ⓧ I'd like to double check the full code

Here is the complete health-check.sh script for comparison:

#!/bin/bash
# Linux System Health Check Script
# Purpose: Perform a daily health check of the Linux system
# Usage: bash ~/health-check.sh

LOGFILE=~/health-report.txt
HOSTNAME=$(hostname)
DATE=$(date '+%Y-%m-%d %H:%M:%S')

{
echo "========================================"
echo " System Health Report"
echo " Host: $HOSTNAME"
echo " Date: $DATE"
echo "========================================"

# Disk Usage
echo ""
echo "[+] Disk Usage:"
df -h

# Memory Usage
echo ""
echo "[+] Memory Usage:"
free -h

# CPU Load
echo ""
echo "[+] CPU Load (1/5/15 min averages):"
uptime

# Failed Services
echo ""
echo "[+] Failed Systemd Services:"
FAILED=$(systemctl --failed --no-legend 2>/dev/null)
if [ -z "$FAILED" ]; then
    echo "  No failed services."
else
    echo "$FAILED"
fi

# Top 5 CPU-Consuming Processes
echo ""
echo "[+] Top 5 CPU Consuming Processes:"
ps -eo user,pid,%cpu,%mem,command --sort=-%cpu | head -6

# Top 5 Memory-Consuming Processes
echo ""
echo "[+] Top 5 Memory Consuming Processes:"
ps -eo user,pid,%cpu,%mem,command --sort=-%mem | head -6

# System Uptime
echo ""
echo "[+] System Uptime:"
uptime -p

# Recent Error Logs
echo ""
echo "[+] Recent Error Logs (Priority 3 and above):"
journalctl -b -p 3 --no-pager 2>/dev/null | tail -10
if [ $? -ne 0 ]; then
    echo "  No error logs available or journalctl not accessible."
fi

echo ""
echo "========================================"
echo " End of Health Report"
echo "========================================"
} | tee "$LOGFILE"

echo ""
echo "Report saved to: $LOGFILE"
Run and verify the script

The moment of truth. Running your script should produce a formatted report covering every diagnostic you practiced manually.

  • Execute the script by running:
bash ~/health-check.sh
  • You should see a formatted report in your terminal with labeled sections: Disk Usage, Memory Usage, CPU Load, Failed Systemd Services, Top 5 CPU Consuming Processes, Top 5 Memory Consuming Processes, System Uptime, and Recent Error Logs.
  • At the very end, you should see Report saved to: ~/health-report.txt.

Seeing a syntax error?

  • A common cause is a missing closing brace } or a missing quote character. Open the file again with nano ~/health-check.sh and check that the curly brace near the bottom is on its own line before | tee "$LOGFILE".
  • If you see Permission denied, run chmod +x ~/health-check.sh again to restore execute permissions.
  • If you see errors about systemctl or journalctl, the script uses 2>/dev/null to suppress those gracefully. If you still see them, double check that 2>/dev/null appears after those commands in your script.

Help me debug my health-check.sh script.

Review the saved health report

The script did not just print to your screen. It also saved a copy of the entire report to a file so you can review it later or share it with your team.

  • View the saved report by running:
cat ~/health-report.txt
  • You should see the same formatted report that appeared in your terminal.

Why save to a file?

Production support teams document platform health for audit trails and shift handoffs. Saving to ~/health-report.txt means you always have the latest report on disk, ready to attach to a ticket or email to a teammate.

The tee command is what makes this possible. It splits output into two streams: one to the terminal so you see results immediately, and one to the file for permanent storage.

Secret mission

Add Network Diagnostics and Automate with Cron

Your health check script covers system resources, but what about the network? Real support engineers also monitor network interfaces, open ports, and connectivity. Take your script to the next level by adding network diagnostics and scheduling it to run automatically every morning.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally on your Windows machine via WSL, so there are no ongoing costs. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • WSL 2 with Ubuntu distribution (installed on Windows).
  • health-check.sh script file in your home directory.
  • health-report.txt generated report file.
  • ~/practice/ directory with practice files.
  • Cron job scheduled to run health-check.sh daily at 7 AM.

Keep everything running

No action needed. Choose this if you are still actively building or plan to extend your health check script with more diagnostics.

  • Your Ubuntu environment stays ready in the Start menu.
  • Your cron job continues to generate daily reports (as long as the cron service is running and WSL is active).
  • WSL uses minimal disk space and no CPU when idle.

Pause - I'll come back to this later

Stop the cron service and close Ubuntu to free up memory. Your files and configuration stay intact for when you return.

  • Stop the cron service so the script does not run on schedule. Run this in your Ubuntu terminal:
  • Close the Ubuntu terminal window.
  • WSL will shut down automatically after all Linux processes stop. Your files remain saved.
sudo service cron stop

When you are ready to resume, open Ubuntu from the Start menu and run sudo service cron start to re-enable scheduled runs.

Delete - I don't want to use this again

Remove all project resources and the Ubuntu distribution from your machine. This permanently deletes all files and settings inside WSL.

  • Remove your cron job by running this in Ubuntu:
crontab -r
  • Delete all project files by running:
rm -rf ~/health-check.sh ~/health-report.txt ~/practice
  • Exit Ubuntu by running:
exit
  • Unregister the Ubuntu distribution from WSL. Open PowerShell as Administrator and run:
wsl --unregister Ubuntu

This is permanent

Running wsl --unregister Ubuntu permanently deletes all data, settings, and software inside your Ubuntu distribution. You cannot undo this.

If you want to use Ubuntu again later, you can reinstall it by running wsl --install in PowerShell.

Nice Work!

Nice Work!

Nice work! You just went from zero Linux experience to running a real system health check script on your own Ubuntu environment.

You've learned how to:

  • Install and configure a Linux environment (Ubuntu via WSL) on your Windows machine from scratch.
  • Monitor system resources (disk, memory, CPU), manage systemd services, and filter logs using the exact commands L2/L3 support engineers use daily.
  • Build a real Bash health check script combining 10+ sysadmin commands into one automated diagnostic tool that outputs a formatted report.
  • Secret Mission: Added network diagnostics and automated the script with cron scheduling.

Ready to quiz yourself?