When writing shell scripts or running automation tools like Ansible, you’ll often see /bin/sh
, /bin/bash
, or even errors like:
set: Illegal option -o pipefail
This confusion stems from differences between bash
and dash
— two popular Unix shells. Let’s explore what they are, how they differ, and when it matters.
What is bash ?
Bash
stands for Bourne Again Shell. It’s:
- A full-featured, powerful scripting shell
- The default on most Linux distributions (like CentOS, Red Hat, Amazon Linux)
- Widely used for scripting because of its extended features
Key Features of Bash:
- Arrays
- Arithmetic expressions
[[ ]]
test syntax- Process substitution
<(...)
- Advanced string manipulation:
${var//a/b}
set -o pipefail
- The
source
command
What is dash ?
dash
stands for Debian Almquist Shell. It’s:
- Lightweight, fast, and strictly POSIX-compliant
- The default
/bin/sh
on Debian and Ubuntu - Ideal for system scripts and fast boot processes
What dash
lacks:
- No arrays
- No
[[ ]]
syntax - No brace expansion
{1..5}
- No process substitution
- No
set -o pipefail
bash
vs dash
: A Side-by-Side
Feature | bash | dash |
POSIX compliant | Mostly | Fully |
Arrays | Yes | No |
[[ … ]] | Yes | No |
set -o pipefail | Yes | No |
Brace expansion ( {1..5} ) | Yes | No |
Speed | Slower | Faster |
Installed by default | Most distros | Debian/Ubuntu |
Example That Works in Bash but Fails in Dash
#!/bin/sh
set -o pipefail
echo "Hello"
This will fail in dash
(/bin/sh
on Ubuntu) with:
/bin/sh: 1: set: Illegal option -o pipefail
It works fine in bash
.
Why This Matters in DevOps & Ansible ?
In tools like Ansible, the shell
module runs commands via /bin/sh
by default. On Ubuntu/Debian systems, /bin/sh
→ dash
, which means:
- Bash-specific scripts will fail unexpectedly
- You must either write portable, POSIX-compliant shell scripts
- Or explicitly use bash with:
shell: |
set -o pipefail
command
args:
executable: /bin/bash
How to Switch /bin/sh
to Bash (if needed)
echo "dash dash/sh boolean false" | sudo debconf-set-selections
sudo dpkg-reconfigure -f noninteractive dash
This will update /bin/sh
→ /bin/bash
.
Best Practices
- Use
#!/bin/bash
when using bash features - Use
#!/bin/sh
only for strictly POSIX-compliant scripts - Always test scripts on the actual shell being used
- For Ansible, use
args: executable: /bin/bash
when needed
#ansible #skillupwithsachin #blogs #bash #dash
Youtube: https://www.youtube.com/@skillupwithsachin