The World Before Bash
To understand the choice, you have to picture the world it was born into. Before Bash, the command line was dominated by the Bourne shell, or `sh`. Created by Stephen Bourne at Bell Labs in the 1970s, it was a powerful tool for its time. It introduced
the core concepts of piping commands and redirecting output that are now second nature. But it had quirks. One of the biggest headaches for programmers was its `test` command, often written with a single bracket: `[`. This wasn't special syntax; it was just a regular program. This meant it followed standard, often frustrating, rules. If you forgot to put quotes around a variable that might contain spaces, your script would crash with a cryptic "too many arguments" error. This made writing robust scripts a minefield of defensive quoting.
A 'Bourne Again' Shell for a New Era
In the late 1980s, Richard Stallman's GNU Project was building a complete, free, and open-source version of the Unix operating system. A crucial missing piece was the shell. They needed a replacement for the proprietary Bourne shell, and programmer Brian Fox was hired to build it. The result was the “Bourne-Again Shell,” or Bash—a name that was both a technical pun and a statement of purpose. The mission was twofold: be compatible enough to run existing `sh` scripts, but also be better. It needed to smooth over the rough edges of its predecessor, incorporating useful features from other popular shells of the era, like the C shell (csh) and KornShell (ksh).
The Decision That Changed Everything
This is where the forgotten decision comes in. Instead of just improving the existing `[` command, Bash introduced a brand new, enhanced syntax: the double bracket, `[[ ... ]]`. This might look like a minor change, but it was a fundamental philosophical shift. Unlike `[`, the double-bracket `[[` is not an external command; it’s a keyword built directly into the shell’s grammar. This special status gave it superpowers. Inside double brackets, variables with spaces didn't cause scripts to explode, removing the most common source of errors for beginners. It also introduced more intuitive ways to combine conditions using `&&` (for AND) and `||` (for OR), and even added advanced features like pattern matching. It was a pragmatic choice to make scripting safer and more powerful, even if it broke strict compatibility.
The Long Shadow of a Single Choice
That decision created a ripple effect that continues today. On one hand, `[[` made Bash scripting dramatically more robust and user-friendly. Complex conditional logic became cleaner and less error-prone. It was a massive quality-of-life improvement that undoubtedly contributed to Bash's wild success as the default shell on most Linux distributions and macOS for many years. On the other hand, it created a permanent fork in the shell scripting world. Scripts written with `[[` are Bash-specific; they won't run on a system that only has the original, POSIX-compliant `sh`. This has led to endless debates online and in style guides: should you write portable scripts using the tricky old syntax, or embrace the safer, more powerful features of Bash? This single, pragmatic design choice—to build a better mousetrap right next to the old one—perfectly captures the spirit of Bash itself: respectful of the past, but not bound by its limitations.











