Tracing the origins of the shell: from the Bourne Shell (1979) to BASH, born at the hands of Brian Fox (1989), why BASH became the de facto standard on almost all Linux servers, the differences between BASH and other shells as well as high-level languages, and when you should choose which.

In episode 0 we made sure the environment was ready — basic Linux CLI skills, an environment with BASH 4.0+/5.0+, and verification that bash --version runs normally — so this episode we'll take a step back to answer a question that's rarely asked but deeply consequential: where did BASH come from, and why did it become the world's standard?
This question isn't just historical trivia. Understanding BASH's background answers three practical questions that will follow you throughout your career: (1) why a script running under #!/bin/bash can produce different results from one under #!/bin/sh, (2) when you should write BASH and when it's wiser to use Python or Go, and (3) why almost every server on the internet — from those running WordPress to banks — still stays loyal to a shell born more than three decades ago. Like understanding the history of a language, understanding the history of the shell means you can not only use it, but know when to use it.
In this episode we'll trace the evolution of the shell from the 1979 Bourne Shell to modern shells, dissect BASH's position as the de facto standard, understand the difference between #!/bin/bash vs #!/bin/sh, compare BASH with high-level languages, and close with the misconceptions that most often mislead beginners.
Before GUIs and desktops, computers were operated through text. The shell — the program that reads commands from the keyboard and passes them to the operating system — was the primary "interface" between humans and the machine. The history of the shell is the history of that interface's evolution.
sh, 1979)In 1979, Stephen Bourne wrote the Bourne Shell for UNIX Version 7 at Bell Labs. It was a turning point: the Bourne Shell wasn't just a command launcher, but a real scripting language — supporting variables, control flow (if, for, while), and file processing. Before it, UNIX shells were simple command executors.
The Bourne Shell became the de facto scripting standard in UNIX because it was tied to the operating system (not to a particular machine) and designed for automated scripts — not just interactive use. Almost everything you think of as "how to write scripts" today is rooted in the Bourne Shell: the if [ kondisi ]; then syntax, for i in ...; do, and # for comments.
csh) and Korn Shell (ksh)In the early 1980s, two rivals emerged:
csh) was written by Bill Joy at Berkeley. Its syntax mimics the C language — like if (kondisi) then and the set x = 1 variable assignment. It was popular among interactive programmers, but gained a poor reputation for scripting due to inconsistent syntax.ksh) was written by David Korn in 1983. It took the strengths of the Bourne Shell and added interactive features from the C Shell: command history, aliases, and job control. ksh became a highly respected shell in the commercial world.In the late 1980s, the GNU project (which would later host Linux) needed a free shell that was compatible with the POSIX standard and equivalent to the Bourne Shell. Brian Fox wrote the Bourne Again Shell — a play on the name "Bourne Shell" — and released it in 1989. BASH inherited the Bourne Shell's legacy, added interactive features from ksh and csh, and kept being developed for years to come.
When Linux emerged in 1991 and began to gain popularity, BASH was already the default shell on almost every distribution. Not because it was the fastest or most elegant — but because it was free, available everywhere, and backward compatible with the Bourne Shell scripts already living on thousands of systems.
If zsh is more "modern" and fish is friendlier, why do servers still use BASH? The answer is a combination of history, availability, and ecosystem power:
Default from the start. BASH has been the default shell on almost all Linux distros since the 1990s. When you log into a server, you're already in BASH — with no extra steps.
POSIX-compliant. BASH follows the POSIX standard (in sh mode), so scripts written for it can run on many Unix-like platforms. This standard makes BASH the "common language" between systems.
Backward compatibility. 40-year-old Bourne Shell scripts still run under BASH. In an enterprise world full of legacy systems, backward compatibility is the biggest selling point.
A massive tooling ecosystem. .bashrc, .bash_profile, functions, aliases, and a million tutorials on the internet all assume BASH. Choosing another shell means swimming against the current.
Enough for 95% of the work. For administration automation — processing logs, moving files, running commands periodically — BASH is more than enough.
| Shell | Release Year | Creator | Characteristics |
|---|---|---|---|
Bourne Shell (sh) | 1979 | Stephen Bourne | Ancestor of scripting; early UNIX standard |
C Shell (csh) | 1979 | Bill Joy | C-style syntax; popular interactively, bad for scripts |
Korn Shell (ksh) | 1983 | David Korn | Blend of sh + csh features; popular in enterprise |
| BASH | 1989 | Brian Fox | De facto Linux standard; sh compatible, feature-rich |
| zsh | 1990 | Paul Falstad | Rich interactive features; default macOS shell & popular among devs |
| fish | 2005 | Axel Liljencrantz | Beginner-friendly, autosuggestions; not POSIX |
sh. That makes it unsuitable for portable server automation.Think of it like spoken languages: zsh and fish are dialects that are fun for chatting (interactive), while BASH is the formal language understood by everyone in the meeting room (the server). You can interact in your favorite dialect, but official documents must be in the formal language.
Note
The "default shell" on macOS since Catalina is zsh, not BASH — but that only applies to interactive sessions. Scripts that start with #!/bin/bash still run as long as BASH is installed. On Linux servers, BASH remains king: check it yourself with echo $SHELL on any production server.
The term POSIX (Portable Operating System Interface) keeps coming up — let's break it down. POSIX is a family of standards defined by the IEEE to ensure applications and scripts can move between Unix-like operating systems. For you, what matters is one concept: the POSIX standard defines the "minimal" behavior of a shell that is guaranteed to exist everywhere.
The consequence is clearest in the shebang — the first line of a script:
#!/bin/sh
#!/bin/bash
#!/usr/bin/env bash#!/bin/sh means "run with a POSIX shell". On modern distros, /bin/sh is often linked to dash (Debian/Ubuntu) — a lightweight, strictly POSIX shell with no BASH features. Scripts with #!/bin/sh must be written with POSIX discipline.#!/bin/bash means "run with BASH" — all BASH features are available. This is the most common choice for the scripts we write in this series.#!/usr/bin/env bash looks up bash from $PATH — more portable across platforms where BASH isn't always located at /bin. The trade-off: env uses PATH, so it can point to the wrong interpreter in unusual environments.Important
Make a clear distinction: #!/bin/bash (the BASH interpreter) vs #!/bin/sh (the POSIX interpreter). BASH features like [[ ]], arrays, and ${var,,} are not available under /bin/sh in dash mode. A #!/bin/sh script that uses BASH features will fail with mysterious errors on Ubuntu. For this series we'll consistently use #!/bin/bash, unless there's a specific portability need.
A recommended practice when you write scripts that must run on many systems:
ls -l /bin/sh
bash --posix --version | head -1lrwxrwxrwx 1 root root 4 ... /bin/sh -> dash
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)The first line shows that /bin/sh on Ubuntu actually points to dash — not BASH. This is why "it runs in the terminal but fails in a script" happens so often: the script uses the #!/bin/sh shebang yet its contents are full of BASH features.
The classic question: wouldn't it be better to use Python or Go? The answer: it depends on the context. BASH isn't Python's rival — they're tools for different jobs. Like a screwdriver and a power drill: the screwdriver is more appropriate for a small screw in a tight spot, the drill for big jobs.
| Aspect | BASH | Python / Go |
|---|---|---|
| Focus | Glue for commands & filesystem | Complex business logic, data structures |
| Startup | Instant, no runtime | Python has startup overhead; Go must compile |
| Running external commands | Natural (ls, grep, awk as first-class citizens) | Needs subprocess/os.exec — more verbose |
| Error handling | Simple, relies on exit codes | Explicit, structured try/except |
| Data structures | Simple arrays, string-centric | Full lists, dicts, objects, classes |
| Type safety | None | Strong (especially Go) |
| Ideal for | Backup, log rotation, server setup, cron, wrappers | Complex data parsing, APIs, large tooling |
The rule of thumb from senior sysadmins:
cp, tar, systemctl, or curl, then BASH is the most concise and clear choice.#!/bin/bash
# Daily backup: compress, move, clean up the old ones
tar -czf /backup/$(date +%F)-data.tar.gz /var/www/data
rsync -a /backup/ /mnt/backup-server/
find /backup -name "*.tar.gz" -mtime +30 -deleteThis script expresses the intent in 4 lines that are immediately readable. Translating it to Python would produce dozens of lines of subprocess.run(...) — with no meaningful benefit. That's BASH's power: conciseness for system automation tasks.
"BASH is the same as the terminal." No. The terminal (emulator) is just the window where you type; BASH is the program running inside it that interprets commands. You can use the same terminal with a different shell — try typing zsh or ksh to switch.
"BASH is a weak programming language, so no need to learn it." Completely wrong. BASH isn't for building applications, but for automation — and in the server world, automation is half the job. Precisely because it's "simple", BASH is the most-executed language in the world (every docker run, every cron, every boot).
"A script that runs in my shell will definitely run on the server." Not automatically. BASH version differences, wrong shebangs, and command differences between distros are the most common sources of errors. Always write an explicit shebang and test in the target environment.
"If you can do Python, why BASH?" Because the two aren't competitors. Backup, log rotation, and server setup are BASH jobs; JSON parsing and business logic are Python jobs. Using Python for cp is a drill for a screw — possible, but not efficient.
"sh and bash are the same thing." On modern Linux, not always. As we saw, /bin/sh on Ubuntu points to dash — a POSIX interpreter without BASH features. Writing #!/bin/sh with BASH-style content is a recipe for errors.
Warning
Always write an explicit shebang and never rely on the shell you're typing in as your "interpreter". The habit of writing #!/bin/bash and testing scripts via bash script.sh will save you from scripts that "run in the terminal but fail in cron" — one of the most frustrating mysteries in the sysadmin world.
In episode 1 we learned that BASH is the result of a long evolution: from the Bourne Shell (1979), which introduced scripting, to ksh and csh as rivals, to BASH by Brian Fox (1989), which won thanks to its position as the default shell, POSIX compatibility, and backward compatibility. We also dissected why BASH became the de facto standard on Linux servers, the crucial difference between #!/bin/bash vs #!/bin/sh (and why /bin/sh on Ubuntu is dash), and BASH's position as an orchestrator that sits alongside — not competes with — high-level languages.
The core takeaways:
#!/bin/bash (the BASH interpreter) differs from #!/bin/sh (POSIX, often dash).sh and bash, and always write an explicit shebang.Now you know why BASH exists. In episode 2 we'll get hands-on: the shebang, execution modes, and your first script — writing hello.sh, understanding chmod +x, and dissecting the fundamental differences between ./hello.sh, bash hello.sh, and source hello.sh, which will determine how you design scripts from here on. See you in episode 2!