Difference between sh and Bash
Categories:
sh vs. Bash: Understanding the Core Differences in Unix Shells

Explore the fundamental distinctions between the traditional 'sh' shell and the widely used 'Bash' (Bourne Again SHell), including features, compatibility, and practical implications for scripting and command-line usage.
In the world of Unix-like operating systems, the shell is your primary interface for interacting with the kernel. It's a command-line interpreter that executes commands and scripts. Two of the most common shells you'll encounter are sh
(Bourne Shell) and Bash
(Bourne Again SHell). While Bash
is often the default shell on many modern Linux distributions, sh
holds historical significance and remains crucial for POSIX compliance and basic scripting. Understanding their differences is vital for writing portable scripts and effectively managing your system.
The Legacy of sh: The Bourne Shell
sh
, or the Bourne Shell, was developed by Stephen Bourne at Bell Labs and released in 1979. It was the first widely available Unix shell and became the standard for Unix systems. Its primary goal was to provide a simple, efficient, and powerful command interpreter and scripting language. sh
is known for its minimalist design and adherence to the POSIX standard, which defines a set of standards for maintaining compatibility between operating systems. This makes sh
scripts highly portable across different Unix-like systems.
#!/bin/sh
echo "Hello from sh!"
# Basic variable assignment and expansion
my_var="World"
echo "Hello, $my_var!"
# Simple conditional statement
if [ -f "/etc/passwd" ]; then
echo "/etc/passwd exists."
fi
A simple 'sh' script demonstrating basic commands and syntax.
Bash: The Modern, Feature-Rich Successor
Bash
, or the Bourne Again SHell, was created by Brian Fox for the GNU Project as a free software replacement for the Bourne Shell. Released in 1989, Bash
is largely compatible with sh
but extends its functionality with numerous enhancements. It incorporates features from other popular shells like csh
(C Shell) and ksh
(Korn Shell), making it a powerful and user-friendly choice for interactive use and complex scripting. Bash
is the default interactive shell on most Linux systems and macOS (up to Catalina).
flowchart TD A[User Input] --> B{Shell Type?} B -->|sh| C[Basic Features] B -->|Bash| D[Advanced Features] C --> E[POSIX Compliant] D --> E D --> F[Interactive Enhancements] D --> G[Extended Scripting] E --> H[Portable Scripts] F --> I[History, Aliases, Job Control] G --> J[Arrays, Regex, Process Substitution] H --> K[Minimal Dependencies] I --> L[Improved User Experience] J --> M[Complex Automation]
Conceptual flow illustrating the feature sets of sh and Bash.
Key Differences and Practical Implications
While Bash
is largely a superset of sh
, several key differences impact how you write scripts and interact with the command line. Understanding these distinctions helps in choosing the right shell for a task and ensuring script portability.
1. Feature Set
Bash
offers a richer set of features compared to sh
. This includes advanced array handling, regular expression matching operators ([[ ... ]]
with =~
), process substitution (<(command)
), enhanced command history, job control, and programmable completion. sh
, by contrast, provides a more fundamental set of tools.
2. Interactive Use
For interactive command-line use, Bash
is generally preferred due to features like command history recall (up/down arrows), tab completion for commands and filenames, aliases, and customizable prompts. sh
typically offers a much more basic interactive experience.
3. Scripting Compatibility and Portability
Scripts written for sh
are generally compatible with Bash
because Bash
aims for sh
compatibility. However, Bash
-specific features will not run in a pure sh
environment. For maximum portability, especially in system startup scripts or embedded systems, sh
is often the preferred choice. The shebang line #!/bin/sh
explicitly tells the system to execute the script using the sh
interpreter, which might be a symlink to dash
(Debian Almquist Shell) on some Linux systems, a very lightweight and POSIX-compliant shell.
4. Syntax Extensions
Bash
introduces several syntax extensions. For example, [[ ... ]]
is a more powerful conditional construct than [ ... ]
(test command) used in sh
, supporting pattern matching and logical operators like &&
and ||
directly. Bash
also has different behavior for certain built-in commands and variable expansions.
#!/bin/bash
echo "Hello from Bash!"
# Bash-specific features:
# Array handling
my_array=("apple" "banana" "cherry")
echo "First element: ${my_array[0]}"
# Regular expression matching
if [[ "hello world" =~ "world" ]]; then
echo "'world' found in string."
fi
# Process substitution
comm -13 <(sort file1.txt) <(sort file2.txt)
# Brace expansion
echo {a..c}.txt
A 'Bash' script showcasing features not available in standard 'sh'.
#!/bin/sh
and stick to POSIX-compliant syntax. If you need advanced features and are certain the target environment has Bash
, then #!/bin/bash
is appropriate.When to Use Which Shell
Choosing between sh
and Bash
depends largely on your requirements:
Use
sh
for:- System startup scripts (
init.d
,rc.d
) where minimal dependencies and maximum portability are critical. - Scripts intended for embedded systems or environments with limited resources.
- Scripts that must adhere strictly to the POSIX standard.
- When you need to ensure your script runs on any Unix-like system, regardless of the default shell.
- System startup scripts (
Use
Bash
for:- Interactive command-line use on modern Linux/macOS systems.
- Complex scripts that benefit from advanced features like arrays, associative arrays, regular expressions, and process substitution.
- Scripts where performance is less critical than development speed and feature availability.
- When you are certain the target environment has
Bash
installed and available.
graph TD A[Script Requirement] --> B{Portability/POSIX?} B -->|Yes| C[Use sh] B -->|No| D{Advanced Features/Interactive?} D -->|Yes| E[Use Bash] D -->|No| C
Decision tree for choosing between sh and Bash for scripting.
/bin/sh
is a symbolic link to a different shell, often dash
(Debian Almquist Shell) or bash
itself. This is done to provide a lightweight, fast, and strictly POSIX-compliant shell for system scripts, while bash
remains the default for interactive user sessions.