What are the key differences between POSIX sh and bash?

Answer

POSIX sh is the standardized shell specification — portable across all UNIX/Linux systems. Scripts starting with #!/bin/sh should use only POSIX features for maximum portability. Key bash-only features not in POSIX sh: double brackets ([[ ]]) with =~ regex, arrays (arr=()), associative arrays (declare -A), process substitution (<(cmd)), local variables in functions (technically not in POSIX), heredoc variations, {a..z} brace expansion, ANSI-C quoting with $'\\n', mapfile/readarray, and PIPESTATUS. On some systems (Alpine Linux, embedded systems) /bin/sh is dash (a minimal POSIX shell), so bash-isms in #!/bin/sh scripts will fail. Use #!/bin/bash explicitly when using bash features and run shellcheck to catch portability issues.