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 pipefailThis 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
sourcecommand
What is dash ?
dash stands for Debian Almquist Shell. It’s:
- Lightweight, fast, and strictly POSIX-compliant
- The default
/bin/shon 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 pipefailIt 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/bashHow to Switch /bin/sh to Bash (if needed)
echo "dash dash/sh boolean false" | sudo debconf-set-selections
sudo dpkg-reconfigure -f noninteractive dashThis will update /bin/sh → /bin/bash.
Best Practices
- Use
#!/bin/bashwhen using bash features - Use
#!/bin/shonly for strictly POSIX-compliant scripts - Always test scripts on the actual shell being used
- For Ansible, use
args: executable: /bin/bashwhen needed
#ansible #skillupwithsachin #blogs #bash #dash
Youtube: https://www.youtube.com/@skillupwithsachin