Skip to content

Language guide

Learn Bash & the Shell

Automating a computer from the command line: scripts, pipes, and the glue of every server.

Bash & the Shell on SkillAIVibe

Runs in your browser

Real Bash & the Shell runs inside a sandbox in your own browser — just-bash 3.4.2 (simulated shell, not a real system bash). Nothing you write is sent to a server. Last verified against the sandbox's checks on .

The Bash & the Shell exercise path

Bash & the Shell practice hub →About the path →

10 exercises in order, each teaching exactly one new idea. Every one runs in this tab, checks your output, and explains what went wrong in plain language.

  1. Trail Signpostecho prints one line, and double quotes keep spacing exactly as typed
  2. Lost and FoundVariables: name=value with no spaces, $name to use it, and single quotes stop expansion
  3. Moving-Day Boxes$((...)) does whole-number arithmetic, and printf formats columns but never adds a newline
  4. Rainwater Tank Gaugeif runs a command and checks its exit status; [ ] compares numbers with -lt/-gt and needs spaces around its brackets
  5. Photo Rename Planfor loops over a word list, and ${name} braces mark where a variable name ends
  6. Downloads Tidy-Upcase matches one value against glob patterns, each branch ending in ;;
  7. Bakery Oven TimesFunctions take $1 $2 arguments, print their result, and are captured with $(...)
  8. Cabin Guest Book> creates a file, >> appends to it, and while read ... done < file reads it line by line
  9. Birdwatching TallyPipes chain sort, uniq -c, grep -c and wc -l into a tally
  10. Library Overdue ReportIFS=, read splits a comma-separated line into fields for that one read

What Bash & the Shell is

Bash is a shell, the program that reads the commands typed into a terminal on Linux and macOS and runs them, and it is also a language for saving those commands in a script. Its building blocks are other programs such as ls, grep and cp, tied together with pipes, variables, conditions and loops. It feels quick for small jobs and fragile for large ones, because nearly everything is text and a missing pair of quotes can change what a line does.

Where Bash & the Shell is used

Automating terminal work
Renaming a folder of photos or backing up a directory with today's date in its name takes a few lines, because the commands you would type by hand go straight into a file.
Server administration
Linux servers are usually managed over SSH with no graphical interface, so setup, maintenance and scheduled cron jobs are commonly shell scripts.
Build and deployment pipelines
On Linux runners, the run steps of a GitHub Actions workflow execute in Bash by default, and the RUN lines of a Dockerfile are shell commands too.
Searching and summarising text
Pipes join grep, sort, uniq and wc, so finding which addresses appear most often in a log file is one line rather than a program.
Development environments
Install scripts, the .bashrc file that sets your aliases and PATH, and the setup commands in a project's README are written for the shell.

Your first Bash & the Shell program

Saved as greet.sh. You can paste it straight into the playground to see it run.

Shell
#!/usr/bin/env bash

name="Asha"
echo "Hello, $name."

for day in Mon Tue Wed; do
  echo "Saving ${name}_${day}.txt"
done

What it prints

Output
Hello, Asha.
Saving Asha_Mon.txt
Saving Asha_Tue.txt
Saving Asha_Wed.txt
  1. Line 1, the shebang, tells the system which program should run the file when you start it as ./greet.sh. /usr/bin/env bash finds Bash wherever it is installed.
  2. Line 3 creates a variable. There must be no spaces around =; with spaces, Bash would try to run a command called name.
  3. Line 4 prints a line with echo. Inside double quotes, $name is replaced by its value; inside single quotes it would be printed literally as $name.
  4. Lines 6 to 8 are a for loop. On each pass, day holds the next word from the list after in, and the lines between do and done run once for it.
  5. Line 7 needs braces because underscores can be part of a variable name. Written as $name_, Bash would look for a variable called name_, find nothing, and print Saving Mon.txt.

Try it in the Bash & the Shell playground →

Run Bash & the Shell on your own computer

There is probably nothing to install. Bash comes with macOS and most Linux distributions (very small container images such as Alpine include only a lighter sh), and Windows can run it through WSL or Git Bash.

  1. Linux and macOS: check the version

    macOS has used zsh as its default interactive shell since Catalina, but bash is still installed, as the old 3.2 release. That runs everything in the first program; features such as associative arrays need Bash 4 or newer, available through Homebrew.

    Shell
    bash --version
  2. Windows: use WSL or Git Bash

    WSL runs a real Linux distribution and is the closest match to a server; run this command in PowerShell opened as administrator, then restart when asked. Git Bash, which comes with Git for Windows, is lighter and enough for learning.

    Shell
    wsl --install
  3. Save the script with Unix line endings

    Save the first program as greet.sh with LF line endings, not the Windows CRLF; VS Code shows which one a file uses in its status bar. The ShellCheck linter points out quoting mistakes as you write.

  4. Make it executable and run it

    chmod +x is needed once per file, and the ./ is required because the shell does not look in the current folder for commands. bash greet.sh also works, without chmod. Avoid sh greet.sh, which on Debian and Ubuntu runs a different shell.

    Shell
    chmod +x greet.sh && ./greet.sh

A learning order for Bash & the Shell

Stages, not a timetable. Each one exists because the next would not make sense without it, and how long each takes depends on how much you write.

  1. Stage 1. Getting around the command line

    • pwd, ls and cd
    • absolute and relative paths
    • mkdir, cp, mv and rm
    • tab completion and history
    • man pages and --help

    A script is a list of commands, so the commands come first. Moving around confidently also helps with every other language, whose tools run in the same terminal.

  2. Stage 2. Pipes, redirection and exit status

    • | between commands
    • >, >> and <
    • standard error and 2>
    • grep, sort, uniq, wc, head and tail
    • exit codes and $?

    Combining small programs is where the shell earns its place. Exit codes, where 0 means success, are what every later if, && and || depends on.

  3. Stage 3. First scripts

    • the shebang and chmod +x
    • variables
    • single versus double quotes
    • command substitution with $(...)
    • arguments: $1, $# and "$@"

    Quoting is the most important habit in Bash, and many confusing beginner bugs trace back to it. It is easiest to learn with small scripts, before loops and functions.

  4. Stage 4. Conditions and loops

    • if with [[ ]] and [ ]
    • file tests such as -f and -d
    • -lt and -gt for numbers, == for strings
    • && and ||
    • for, while and while read
    • case

    Bash has two test syntaxes and separate operators for numbers and strings, which is unusual. Sorting that out once makes the conditions in any script readable.

  5. Stage 5. Functions and safer scripts

    • functions and local variables
    • return codes versus printed output
    • set -euo pipefail and its limits
    • trap for clean-up
    • ShellCheck

    Scripts that other people run should stop loudly when something fails. The strict-mode options help but have exceptions, so it is worth knowing exactly what they catch.

  6. Stage 6. Real-world automation

    • find and xargs
    • sed and awk basics
    • PATH and .bashrc
    • scheduling with cron
    • ssh and scp
    • when to switch to Python

    These are the tools scripts spend their time calling. Recognising when a script has outgrown Bash, usually when it needs real data structures, is a skill in itself.

Mistakes beginners make in Bash & the Shell

Leaving variables unquoted
With file="my notes.txt", the command rm $file splits the value at the space and tries to delete two files, my and notes.txt. Nothing warns you, and the script works until the first filename with a space arrives. Write "$file" in double quotes by default.
Putting spaces around = in an assignment
name = "Asha" makes Bash run a command called name with two arguments, which fails with name: command not found. An assignment has to be one unbroken word: name="Asha".
Writing [ ] without spaces inside
[ is a command, not punctuation, and its last argument must be ]. So if [$count -gt 3] tries to run a command named [3 when count is 3, and fails with [3: command not found. Write if [ "$count" -gt 3 ]; the same spacing applies to [[ ]].
Saving the script with Windows line endings
Windows editors can end lines with CRLF, a carriage return plus a newline. Bash treats the carriage return as part of each command, so a blank line fails with $'\r': command not found, even though the file looks normal. Switch the editor to LF, convert the file with dos2unix, and add *.sh text eol=lf to .gitattributes.
Running a Bash script with sh
On Debian and Ubuntu, sh is a smaller shell called dash, not Bash. sh greet.sh ignores the shebang and fails on Bash features such as [[ ]] or arrays, with errors like [[: not found. Run it as ./greet.sh or bash greet.sh.

Strengths and trade-offs

Where it is strong

  • Already installed on Linux servers and macOS, so a script runs on a fresh machine with nothing added first.
  • Built for combining programs: one pipeline of existing tools can replace a page of code in a general-purpose language.
  • What you type at the prompt is the same language you script in, so every command learned interactively can be automated.
  • Transfers directly to CI configuration, Dockerfiles, remote servers and the install instructions of developer tools.

Where it is not

  • A failing command does not stop a script by default. set -e helps, but it has documented exceptions, such as commands tested by if or joined with && and ||.
  • Quoting and word-splitting bugs often surface only with unusual input, such as filenames containing spaces or starting with a dash.
  • Variables are strings and built-in arithmetic is whole numbers only ($((7 / 2)) is 3); decimals, dates and JSON mean calling bc, date or jq.
  • Portability is harder than it looks: sh is not Bash, macOS ships Bash 3.2, and sed behaves differently on macOS and Linux.

Who Bash & the Shell is for

Anyone who writes code, runs servers or handles data files on Linux or macOS benefits from knowing the shell, so Bash is a skill to build alongside another language rather than instead of one. As your only language it is a poor choice: the quoting rules, the lack of real data types and the weak error handling make general programming ideas hard to learn cleanly. Learn enough to move around, pipe commands together and write short scripts, then reach for Python or a similar language when a task needs real logic. If you work only on Windows and never touch Linux machines, PowerShell may serve you better.

Questions about learning Bash & the Shell

What is the difference between the terminal, the shell and Bash?
The terminal is the window that displays text and passes on your typing. The shell is the program inside it that runs your commands. Bash is one shell; zsh, fish, dash and PowerShell are others. People use the words loosely, but a script starting with #!/usr/bin/env bash is asking for Bash specifically.
My Mac uses zsh. Should I learn zsh instead?
For everyday typing, zsh and Bash are close enough that most habits carry over. For scripts, write Bash with a #!/usr/bin/env bash line: it runs in Bash whichever shell you use interactively, and also on Linux servers, where zsh is often not installed. Keep in mind that macOS bundles the old Bash 3.2.
Should I learn Bash or PowerShell on Windows?
It depends on where your code will run. For Linux servers, containers, cloud machines or open-source tooling, learn Bash through WSL or Git Bash. For administering Windows computers and Microsoft services, PowerShell is the native tool, and it passes structured objects between commands rather than text. Pipes, variables and loops carry over either way.
When should a Bash script become a Python script?
There is no fixed line, but some signs are reliable: you need lists of records, you are parsing JSON or CSV by hand, you need decimal arithmetic, the error checks have become a tangle, or you have to scroll to follow the script. Bash is good at running and connecting commands; once most of the work is logic, a general-purpose language is shorter and easier to test.

The primary source

When this guide and the official documentation disagree, the documentation is right and we would like to hear about it.

Other languages

All languages and paths · Programming glossary · Your progress