bash / zsh / fish
The shell is your command interpreter. Bash is the default on Linux; zsh on macOS; many flavours exist. Pick one, learn its features, install a sensible config.
Linux — shells overview
EXAMPLE
# ===== Which shell am I in? ===== echo $0 # current shell name echo $SHELL # default login shell ps -p $$ # parent process: the shell binary # ===== Common shells ===== # bash GNU Bourne-Again Shell; default on most Linux distros # zsh Z shell; default on macOS since Catalina; rich completion + themes # fish Friendly Interactive Shell; sane defaults; not POSIX-compatible # dash Debian Almquist; small, POSIX, fast; symlinked as /bin/sh on Debian # ash BusyBox shell; used in Alpine containers # ksh KornShell; ancestor of bash + zsh; rare today # ===== Where the config lives ===== # bash: ~/.bashrc (interactive), ~/.bash_profile / ~/.profile (login) # zsh: ~/.zshrc (interactive), ~/.zprofile (login) # fish: ~/.config/fish/config.fish # ===== Change your default shell ===== chsh -s /bin/zsh # Log out + back in. # Inside a script: #!/usr/bin/env bash # or #!/bin/sh for portable POSIX scripts # ===== Essentials any shell gives you ===== # - Variables: NAME='Alex' -> echo $NAME # - Pipes: cmd1 | cmd2 # - Redirection: > >> < 2> 2>&1 # - Background: cmd & # - Job control: fg, bg, jobs, kill %1 # - History: ! prefix, Ctrl+R reverse search # - Tab completion (richer in zsh + fish) # ===== Frameworks + themes ===== # zsh: oh-my-zsh, prezto, starship prompt # bash: bash-it, starship # fish: built-in goodies, oh-my-fish # ===== Starship (cross-shell prompt) ===== curl -sS https://starship.rs/install.sh | sh # Add to ~/.zshrc: eval "$(starship init zsh)" # ===== POSIX vs feature-rich ===== # Production scripts: target POSIX sh; portable across distros + Alpine containers # Interactive use: pick your favourite (zsh or fish for features; bash for ubiquity) # ===== Patterns to internalise ===== # - One shell per machine for interactive use; scripts target POSIX where possible # - shellcheck for every script # - History settings: HISTFILE, HISTSIZE, ignoring duplicates # - set -euo pipefail at the top of scripts that should fail loudly # ===== Pitfalls ===== # - #!/bin/sh assuming bash features (arrays, [[ ]]) -> breaks on Alpine # - chsh to fish for scripting use; many tools assume bash on stdin # - Letting your dotfiles drift across machines; use a chezmoi / yadm setup # - Sourcing untrusted scripts in your rc file
Why it matters
Pick one shell for interactive use, learn it well, and add a sensible prompt. For scripts, target POSIX sh and lint with shellcheck. The shell is the IDE for everything outside an editor — invest in it once and reap the productivity for years.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
# bash is the default on most servers. # zsh is the default on modern macOS. # fish is friendly but not POSIX. echo $0Try it Yourself »
Discussion
Loading…