Compatibility notes

Rush aims to be useful to people who already know Bash, while also providing a POSIX mode for scripts that want POSIX-facing behavior. This page records known, intentional, or currently accepted compatibility differences when another shell's behavior is a common reference point.

These notes are not a complete compatibility matrix. They are for cases where Rush makes a deliberate choice, where common system shells disagree, or where an older Bash version behaves differently from current Bash. The decision-making rules live in the conformance policy.

POSIX mode

Assigning defaults to positional parameters

Rush treats an attempt to assign a default value to a positional parameter with ${parameter:=word} as a fatal expansion error when the assignment would be required.

set -- ''
printf '%s\n' ${1:=fallback}
printf 'after\n'

POSIX parameter assignment through := assigns only shell variables; positional parameters cannot be assigned this way. Rush reports the error and does not print after. This matches dash, ksh93, and yash. Bash 3.2 and Bash 5.3 in POSIX mode report the error but continue executing the script. zsh 5.9 in sh emulation assigns the positional parameter and continues.

Non-integer variables in arithmetic expansion

Rush treats a variable whose contents are not a valid integer constant as an arithmetic expansion error when the variable is used as an arithmetic operand.

x=abc
printf '%s\n' "$((x))"
printf 'after\n'

POSIX requires arithmetic expansion to fail with a diagnostic when the contents of a shell variable used in the expression are not recognized by the shell. Rush reports the error and does not print after. This matches dash and ksh93. Bash 3.2 and Bash 5.3 in POSIX mode instead expand this case to 0 and continue executing the script.

Invalid break and continue counts

Rush treats break and continue operands that are not positive decimal integers as fatal errors in a non-interactive shell.

for x in a b
do
  break 0
  printf 'after\n'
done

POSIX specifies that applications using break or continue with an operand shall use a positive decimal integer. Rush reports the error and exits the non-interactive script. This matches dash and yash. Bash 3.2 and Bash 5.3 in POSIX mode report break 0 and continue 0 as errors but continue executing the surrounding script with status 1 for the failed special built-in.

Bash

Bash 3.2

macOS still ships Bash 3.2 as /bin/bash. Rush does not treat Bash 3.2 behavior as the sole Bash compatibility target when newer Bash versions and POSIX-mode shells agree on different behavior.

Unsetting readonly variables in POSIX mode

In non-interactive POSIX mode, Rush treats an attempt to unset a readonly variable as a fatal error for the current shell execution environment.

readonly ro=value
unset ro
printf 'after\n'

Rush reports the error and does not print after. This matches dash and modern Bash POSIX mode. Bash 3.2 POSIX mode reports the error but continues executing the script.

POSIX case fall-through with ;&

Rush accepts the POSIX ;& case clause terminator, which executes the matching clause and then continues by executing subsequent clause bodies without testing their patterns until a ;; terminator or the end of the case command.

case x in
  x) printf 'one\n' ;&
  y) printf 'two\n' ;;
esac

Rush and modern Bash POSIX mode print both lines. Bash 3.2 POSIX mode rejects ;& as a syntax error.

Bash case test-next with ;;& in POSIX mode

Rush supports the Bash-style ;;& case clause terminator in its default mode, but rejects it when --posix is requested because POSIX defines ;; and ;&, not ;;&.

Bash 5.3 accepts ;;& even when started with --posix. Rush intentionally diverges there so --posix remains a stricter POSIX-facing mode.

Alias substitution after leading redirections in POSIX mode

Rush recognizes the first command word as an alias candidate even when a simple command starts with one or more redirections.

alias say='printf alias-hit\\n'
>/tmp/rush-alias.out say
cat /tmp/rush-alias.out

Rush, dash, yash, and modern Bash POSIX mode print alias-hit. Bash 3.2 POSIX mode does not expand the alias in this position, so the command search sees say instead.