Free Online Course · Self-paced · Hands-on

Bash Shell Scripting Tutorial (Free Course)

Free Bash shell scripting course: quoting, loops, arrays, pipelines, strict mode, traps, and real admin scripts, each lesson tested on Bash 5.2 on RHEL 10.

  • 12 chapters
  • 72 lessons
  • ~20h
  • Beginner to Advanced
  • Tested with Bash 5.2.x
  • Updated Sep 2026
Bash Shell Scripting Tutorial (Free Course)
By Last updated

About this course

This free course teaches Bash shell scripting from your first script to production scripts you can schedule on a server. The chapters follow the order in which Bash problems usually show up: quoting and variables, then tests and loops, arrays and expansions, pipelines, and finally error handling, traps, testing, and real admin projects. When a lesson and the GNU Bash manual seem to disagree, trust the manual.

Each lesson was run on a RHEL 10.2 lab host with Bash 5.2, and the output blocks are the real transcripts from those runs. The scripts themselves are not tied to Red Hat. They run on any Linux distribution with Bash installed, and lessons point out the few places where a feature needs a newer Bash or behaves differently under sh.

If Bash is new to you, go through the chapters in order. Quoting comes before arrays, exit codes before strict mode, and getopts before the CLI project, because each later lesson leans on the earlier one. If you already write scripts, jump to strict mode, trap, or the real-world projects chapter.

What you'll learn

  • Write and run scripts with the right shebang, comments, and quoting
  • Work with variables, environment variables, user input, script arguments, and arithmetic
  • Branch on exit codes with if, case, [[ ]], regex matching, and globbing
  • Loop with for, while, and select, and package logic in functions that accept getopts options
  • Handle indexed and associative arrays, parameter expansion, command substitution, and IFS word splitting
  • Redirect streams, build pipelines with pipefail, and use heredocs, process substitution, subshells, and file descriptors
  • Harden scripts with strict mode, traps, mktemp, logging, ShellCheck, and Bats tests
  • Run jobs in parallel, block duplicate runs with flock, schedule with cron or systemd timers, and build complete admin scripts

Who this course is for

  • Linux sysadmins who type the same commands every week and want them in a script they can trust
  • Developers and DevOps engineers writing CI steps, container entrypoints, and deployment hooks in Bash
  • RHCSA candidates working on the "Create simple shell scripts" objective who want to go past the basics
  • Anyone who copies Bash from Stack Overflow and wants to understand why quoting and exit codes behave the way they do

Prerequisites

  • A Linux machine, VM, or WSL with Bash. The lessons were run on Bash 5.2, most work on Bash 4.x, and each lesson notes any feature that needs a newer version
  • Comfort opening a terminal, editing a file with nano or vim, and moving around with cd, ls, and mkdir
  • A normal user account, with sudo only for the scheduling, bulk user creation, and health check lessons
  • Optional tools from your distribution's repositories, such as ShellCheck, shfmt, Bats, jq, and curl. No paid software or cloud account is needed

Versions and testing environment

Every command in this course was run on this stack

ComponentVersionNotes
Bash 5.2.x bash-5.2.26-6.el10 from the RHEL 10.2 repositories. The Bash 5.3 section of the command substitution lesson uses a source build
RHEL 10.2 (Coughlan) The lab host for every lesson. The scripts are not distribution-specific and run anywhere Bash is installed
ShellCheck and shfmt 0.10.x and 3.13.x Used in the linting lesson, best practices, and the CLI capstone
Bats 1.11.x Used in the testing lesson and the CLI capstone
jq and curl 1.7.x and 8.12.x Used in the JSON and API lessons and for optional output in the project scripts

Syllabus

12 chapters · 72 lessons · ~20h of reading

  1. 1 Beginner — Bash Foundations 5 lessons · ~50 min
    1. Part 1 How to write and run a Bash script in Linux 7 min read
    2. Part 2 Bash vs sh — differences and which shell to use 14 min read
    3. Part 3 Bash shebang — 11 min read
    4. Part 4 Bash comments — single-line, multiline, and ShellCheck directives 8 min read
    5. Part 5 Bash single vs double quotes and escaping 10 min read
  2. 2 Beginner — Variables, Input and Basic Data 9 lessons · ~1h 29m
    1. Part 6 Bash variables — create, use, unset and declare 9 min read
    2. Part 7 Bash environment variables and export 10 min read
    3. Part 8 Bash startup files — .bashrc vs .bash_profile vs .profile 13 min read
    4. Part 9 Bash read command — user input, passwords and timeouts 14 min read
    5. Part 10 Bash script arguments — $1, $#, $@ and shift 10 min read
    6. Part 11 Get Bash script name, path and directory 9 min read
    7. Part 12 Bash echo vs printf — output, newlines and formatting 7 min read
    8. Part 13 Bash arithmetic — $(( )), (( )) and decimal math 10 min read
    9. Part 14 Concatenate strings in Bash 7 min read
  3. 3 Beginner — Exit Status, Tests and Decisions 9 lessons · ~1h 34m
    1. Part 15 Bash exit codes — $?, exit, &&, || and ! 10 min read
    2. Part 16 Bash [ ] vs [[ ]] vs (( )) — which test to use 12 min read
    3. Part 17 Bash if, elif, else with examples 10 min read
    4. Part 18 Bash case statement with examples 10 min read
    5. Part 19 Compare strings in Bash 11 min read
    6. Part 20 Compare numbers in Bash 10 min read
    7. Part 21 Check if file or directory exists in Bash 9 min read
    8. Part 22 Bash regex — =~ and BASH_REMATCH 9 min read
    9. Part 23 Bash wildcards and globbing 13 min read
  4. 4 Beginner — Bash Loops 5 lessons · ~53 min
    1. Part 24 Bash for loop — lists, ranges, arrays and C-style 12 min read
    2. Part 25 Bash while loop — conditions, infinite loops and while read 11 min read
    3. Part 26 Bash break and continue — exit or skip loops 10 min read
    4. Part 27 Read a file line by line in Bash 9 min read
    5. Part 28 Create interactive menus with Bash select 11 min read
  5. 5 Beginner — Functions and Command-Line Interfaces 3 lessons · ~39 min
    1. Part 29 Bash functions — arguments, local variables and return values 13 min read
    2. Part 30 Bash source vs execute a script 12 min read
    3. Part 31 Bash getopts — parse short options and handle long options 14 min read
  6. 6 Intermediate — Arrays and Bash Expansions 8 lessons · ~1h 27m
    1. Part 32 Bash arrays — create, append, loop, slice and delete 11 min read
    2. Part 33 Bash associative arrays — key-value maps 12 min read
    3. Part 34 Split a string into an array in Bash 10 min read
    4. Part 35 Bash mapfile / readarray — read lines into an array 9 min read
    5. Part 36 Bash IFS and word splitting explained 12 min read
    6. Part 37 Bash parameter expansion — defaults, replace, trim and substring 11 min read
    7. Part 38 Bash command substitution — $() vs backticks 9 min read
    8. Part 39 Bash shell expansions — expansion order, word splitting and globbing 13 min read
  7. 7 Intermediate — stdin/stdout, Pipelines and Execution Environments 6 lessons · ~1h 11m
    1. Part 40 Bash redirection — stdin, stdout and stderr 11 min read
    2. Part 41 Bash pipes — pipefail, PIPESTATUS and exit codes 11 min read
    3. Part 42 Bash heredoc and here string — << and <<< 12 min read
    4. Part 43 Bash process substitution — <() and >() 10 min read
    5. Part 44 Bash subshells — () vs {} and variable scope 13 min read
    6. Part 45 Bash file descriptors — exec, FD 3, read -u and dynamic FDs 14 min read
  8. 8 Advanced — Writing Reliable Production Bash 10 lessons · ~2h 6m
    1. Part 46 Bash set and shopt — configure shell options 12 min read
    2. Part 47 Bash strict mode — set -euo pipefail explained 13 min read
    3. Part 48 Bash error handling patterns 15 min read
    4. Part 49 Bash trap — signals, EXIT and cleanup 15 min read
    5. Part 50 Create secure temporary files with mktemp 9 min read
    6. Part 51 Logging in Bash scripts 14 min read
    7. Part 52 Debug Bash scripts with bash -x, PS4 and LINENO 10 min read
    8. Part 53 Lint and format Bash with ShellCheck and shfmt 11 min read
    9. Part 54 Test Bash scripts with Bats 12 min read
    10. Part 55 Bash best practices for production scripts 15 min read
  9. 9 Advanced — Processes, Parallelism and Scheduling 5 lessons · ~1h 4m
    1. Part 56 Run Bash commands in background — &, $! and wait 13 min read
    2. Part 57 Run Bash commands in parallel and capture exit codes 13 min read
    3. Part 58 Prevent duplicate Bash scripts with flock 14 min read
    4. Part 59 Measure and limit Bash script execution time 9 min read
    5. Part 60 Schedule Bash scripts with cron and systemd timers 15 min read
  10. 10 Practice — Bash as Automation Glue 5 lessons · ~1h 15m
    1. Part 61 Text processing in Bash with grep, sed, awk, cut, sort and uniq 17 min read
    2. Part 62 Parse JSON in Bash with jq 13 min read
    3. Part 63 Bash API scripts with curl and jq 17 min read
    4. Part 64 Automate SSH commands with Bash 17 min read
    5. Part 65 Bash as a Docker entrypoint — PID 1, signals and exec 11 min read
  11. 11 Practice — Real-World Bash Projects 6 lessons · ~1h 51m
    1. Part 66 Bash disk usage alert script 21 min read
    2. Part 67 Linux system health check script in Bash 23 min read
    3. Part 68 Bash backup script with rsync/tar, logging and locking 13 min read
    4. Part 69 Bash log analyzer script 21 min read
    5. Part 70 Create Linux users from a file with Bash 17 min read
    6. Part 71 Build a production-ready Bash CLI script 16 min read
  12. 12 Reference — Bash Cheat Sheet 1 lesson
    1. Part 72 Bash cheat sheet — quick syntax reference Coming soon

Hands-on labs

6 guided builds you run yourself

  1. Build a disk usage alert script

    Parse df -P, alert on warning and critical thresholds without repeating yourself, send recovery notices, and schedule it with cron under flock.

  2. Write a system health check

    Score CPU, load, memory, swap, disk, inodes, and failed systemd units against thresholds and return an exit code monitoring can act on.

  3. Automate backups with rsync

    Take incremental snapshots with logging, retention, and locking, run them from cron, and prove the files restore.

  4. Analyze web server logs

    Report top IPs, paths, user agents, 4xx and 5xx responses, and byte totals from an Nginx log in a single gawk pass, with CSV export.

  5. Create Linux users from a file

    Validate usernames, shells, and groups from a colon-delimited file, skip existing accounts, and do a dry run before any user is created.

  6. Build a tested command-line tool

    Parse short and long options, validate arguments with predictable exit codes, test the tool with Bats, and run the checks in CI.

Where to go after this course

  • GNU Bash manualThe authoritative reference for expansions, builtins, and shell options when a lesson only covers the common cases.
  • Shell scripting interview Q&ATest yourself on the questions that come up in sysadmin and DevOps interviews.
  • RHCSA coursePut the scripting chapters to work on the full Red Hat administrator syllabus.
  • Ansible courseMove to Ansible once you are running the same script across a fleet of servers.

Frequently Asked Questions

Should I write Bash scripts or POSIX sh scripts?

Write Bash when you control the machines and want arrays, [[ ]], and pipefail, and start the script with a Bash shebang so it never runs under another shell by accident. Write POSIX sh when the script has to run on minimal systems such as Alpine containers or BusyBox, where Bash may not be installed. On Debian and Ubuntu, /bin/sh is dash rather than Bash, so a Bash script run as sh script.sh can fail there even though it works on RHEL.

Which Bash version is current, and does it matter?

The current upstream release is Bash 5.3, released in July 2025, with patch releases since. RHEL 10 ships Bash 5.2, which is what these lessons use. Run bash --version or echo "$BASH_VERSION" to check yours. Most scripts do not care about the difference between 5.x releases, but associative arrays, mapfile, and several expansions need Bash 4 or newer, and Bash 5.3 adds a form of command substitution that runs in the current shell instead of a subshell.

Will these scripts work on macOS or WSL?

WSL runs a real Linux distribution, so the lessons work there as written. macOS is different. Its /bin/bash is still Bash 3.2 and zsh has been the default login shell since macOS Catalina, so associative arrays and mapfile fail out of the box. Install a current Bash with Homebrew, start scripts with #!/usr/bin/env bash, and watch for BSD versions of sed, date, and stat, whose options differ from the GNU tools on Linux.

When should I use Python instead of Bash?

Stay in Bash while the script mostly runs other commands, moves files, and checks exit codes. Switch to Python once it needs to parse JSON or CSV in more than one place, retry API calls with backoff, or keep nested data in memory. A useful warning sign is a Bash script that has grown past a few hundred lines or leans on eval. At that point a Python script is usually shorter and easier to test.

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with 15+ years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)