210 lines
6.5 KiB
Markdown
210 lines
6.5 KiB
Markdown
# `bash` Compatibility Reference
|
|||
|
|
|
||
|
|
This document details `brush`'s compatibility with `bash`, including supported features, known limitations, and how to report issues.
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
`brush` aims for high compatibility with `bash`. We validate this through **1700+ compatibility test cases** that compare behavior against `bash` as an oracle.
|
||
|
|
|
||
|
|
**Compatibility snapshot:** Production-ready for most use cases. Your `.bashrc`, aliases, functions, and completions should "just work."
|
||
|
|
|
||
|
|
## Fully Supported Features ✅
|
||
|
|
|
||
|
|
### Shell Syntax & Control Flow
|
||
|
|
|
||
|
|
- `if`/`then`/`elif`/`else`/`fi` conditionals
|
||
|
|
- `for`, `while`, `until` loops
|
||
|
|
- Arithmetic `for` loops: `for ((i=0; i<10; i++))`
|
||
|
|
- `case`/`esac` pattern matching
|
||
|
|
- `&&`, `||` conditional execution
|
||
|
|
- Subshells `()` and command grouping `{}`
|
||
|
|
- Pipelines and pipeline negation `!`
|
||
|
|
- Coprocesses: `coproc { ... }` and `coproc NAME { ... }`
|
||
|
|
|
||
|
|
### Expansions
|
||
|
|
|
||
|
|
- Brace expansion: `{a,b,c}`, `{1..10}`, `{a..z}`
|
||
|
|
- Parameter expansion: `${var:-default}`, `${var:+set}`, `${var#pattern}`, `${var%pattern}`, `${var//find/replace}`, etc.
|
||
|
|
- Command substitution: `$(cmd)`, `` `cmd` ``
|
||
|
|
- Arithmetic expansion: `$((expr))`
|
||
|
|
- Process substitution: `<(cmd)`, `>(cmd)`
|
||
|
|
- Tilde expansion: `~`, `~user`
|
||
|
|
- Globbing: `*`, `?`, `[...]`
|
||
|
|
- Extended globbing: `?(pat)`, `*(pat)`, `+(pat)`, `@(pat)`, `!(pat)`
|
||
|
|
- `globstar`: `**` recursive matching
|
||
|
|
|
||
|
|
### Builtins (50+)
|
||
|
|
|
||
|
|
- **I/O:** `echo`, `printf`, `read`, `mapfile`/`readarray`
|
||
|
|
- **Variables:** `declare`, `local`, `export`, `unset`, `readonly`, `typeset`
|
||
|
|
- **Control:** `break`, `continue`, `return`, `exit`
|
||
|
|
- **Navigation:** `cd`, `pushd`, `popd`, `dirs`, `pwd`
|
||
|
|
- **Jobs:** `jobs`, `fg`, `bg`, `wait`, `kill`
|
||
|
|
- **Completion:** `complete`, `compgen`, `compopt`
|
||
|
|
- **History:** `history`, `fc`
|
||
|
|
- **Testing:** `test`, `[`, `[[`
|
||
|
|
- **Sourcing & introspection:** `.`, `source`, `eval`, `caller`
|
||
|
|
- **Misc:** `alias`, `unalias`, `hash`, `type`, `command`, `builtin`, `enable`, `help`, `times`, `ulimit`, `umask`, `trap`, `shopt`, `set`, `shift`, `getopts`
|
||
|
|
|
||
|
|
### Arrays
|
||
|
|
|
||
|
|
- Indexed arrays: `arr=(a b c)`, `${arr[0]}`, `${arr[@]}`
|
||
|
|
- Associative arrays: `declare -A map`
|
||
|
|
- Array slicing: `${arr[@]:start:length}`
|
||
|
|
- Array operations: `${#arr[@]}`, `${!arr[@]}`, `${!arr[*]}`
|
||
|
|
|
||
|
|
### Job Control
|
||
|
|
|
||
|
|
- Background execution: `cmd &`
|
||
|
|
- Suspend/resume: Ctrl+Z, `fg`, `bg`
|
||
|
|
- Job listing: `jobs`
|
||
|
|
- Process groups and pipelines
|
||
|
|
|
||
|
|
### Dynamic Variables
|
||
|
|
|
||
|
|
- `RANDOM`, `SRANDOM`
|
||
|
|
- `LINENO`, `FUNCNAME`, `BASH_SOURCE`
|
||
|
|
- `EPOCHSECONDS`, `EPOCHREALTIME`
|
||
|
|
- `SECONDS`
|
||
|
|
- `PWD`, `OLDPWD`
|
||
|
|
- `BASH_VERSINFO`, `BASH_VERSION`
|
||
|
|
|
||
|
|
### Programmable Completion
|
||
|
|
|
||
|
|
- Compatible with [`bash-completion`](https://github.com/scop/bash-completion)
|
||
|
|
- Git, Docker, systemctl, etc. completions work out of the box
|
||
|
|
- `complete`, `compgen`, `compopt` builtins
|
||
|
|
|
||
|
|
### Redirection
|
||
|
|
|
||
|
|
- Standard: `>`, `>>`, `<`, `2>&1`
|
||
|
|
- Here documents: `<<EOF`, `<<-EOF` (tab-stripped), `<<<` (here strings)
|
||
|
|
- File descriptor manipulation: `>&n`, `<&n`, `n>&m`
|
||
|
|
- Process substitution redirects: `>(cmd)`, `<(cmd)`
|
||
|
|
- Clobber control: `>|`, `set -o noclobber`
|
||
|
|
|
||
|
|
## Partially Supported Features 🔷
|
||
|
|
|
||
|
|
### Traps
|
||
|
|
|
||
|
|
| Status | Feature |
|
||
|
|
|--------|----------|
|
||
|
|
| ✅ | `DEBUG` trap |
|
||
|
|
| ✅ | `ERR` trap |
|
||
|
|
| ✅ | `EXIT` trap |
|
||
|
|
| 🔷 | Signal traps (`SIGINT`, `SIGTERM`, etc.) — in progress |
|
||
|
|
|
||
|
|
### Key Bindings (`bind`)
|
||
|
|
|
||
|
|
| Status | Feature |
|
||
|
|
|--------|---------|
|
||
|
|
| ✅ | Basic `bind` support |
|
||
|
|
| ✅ | `bind -x` for custom key-bound commands |
|
||
|
|
| 🔷 | Advanced bind features — in progress |
|
||
|
|
|
||
|
|
### Shell Options
|
||
|
|
|
||
|
|
| Status | Feature |
|
||
|
|
|--------|---------|
|
||
|
|
| ✅ | Common options: `errexit`, `pipefail`, `extglob`, `globstar`, `noclobber`, `nounset`, `failglob` |
|
||
|
|
| 🔷 | Less common options — in progress |
|
||
|
|
|
||
|
|
## Not Yet Supported Features 🚧
|
||
|
|
|
||
|
|
These features are on our roadmap but not yet implemented:
|
||
|
|
|
||
|
|
### `select` Statement
|
||
|
|
|
||
|
|
The `select` builtin for creating menu-driven scripts is not yet implemented.
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Not yet supported
|
||
|
|
select opt in "Option A" "Option B" "Quit"; do
|
||
|
|
case $opt in
|
||
|
|
"Option A") echo "A";;
|
||
|
|
"Option B") echo "B";;
|
||
|
|
"Quit") break;;
|
||
|
|
esac
|
||
|
|
done
|
||
|
|
```
|
||
|
|
|
||
|
|
### `wait -n`
|
||
|
|
|
||
|
|
The `wait -n` option to wait for the next background job to complete is not implemented.
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Not yet supported
|
||
|
|
job1 &
|
||
|
|
job2 &
|
||
|
|
wait -n # Wait for whichever finishes first
|
||
|
|
```
|
||
|
|
|
||
|
|
### `BASH_COMMAND` Variable
|
||
|
|
|
||
|
|
The special variable `BASH_COMMAND` that contains the currently executing command is currently only available in trap contexts.
|
||
|
|
|
||
|
|
### `disown` and `logout`
|
||
|
|
|
||
|
|
These job control builtins are not yet implemented.
|
||
|
|
|
||
|
|
## Known Edge Cases
|
||
|
|
|
||
|
|
These areas have known differences from `bash` in edge cases. Most users won't encounter these, but they're documented for completeness.
|
||
|
|
|
||
|
|
### IFS (Input Field Separator)
|
||
|
|
|
||
|
|
There are ~10 known edge cases where IFS word splitting behavior differs from `bash`, particularly around:
|
||
|
|
|
||
|
|
- Non-whitespace IFS characters and empty field creation
|
||
|
|
- Mixed whitespace and non-whitespace IFS
|
||
|
|
- Leading/trailing delimiter handling
|
||
|
|
|
||
|
|
### `printf` Format Specifiers
|
||
|
|
|
||
|
|
Some advanced `printf` format specifiers behave differently (~8 known cases), particularly features not supported by the underlying `uucore` library.
|
||
|
|
|
||
|
|
### Arithmetic Expressions
|
||
|
|
|
||
|
|
- Division by zero handling may differ in `errexit` mode
|
||
|
|
- `$(( exit N ))` syntax edge case
|
||
|
|
|
||
|
|
### Aliases
|
||
|
|
|
||
|
|
Some complex alias expansion scenarios differ from `bash` (see GitHub issues #57, #286).
|
||
|
|
|
||
|
|
## Test Suite Statistics
|
||
|
|
|
||
|
|
- **Total test cases:** 1700+
|
||
|
|
- **Known failures:** ~125
|
||
|
|
- **Most failures are edge cases** in IFS handling and printf
|
||
|
|
|
||
|
|
The test suite runs on every PR and compares behavior against `bash` as an oracle.
|
||
|
|
|
||
|
|
## Version Compatibility
|
||
|
|
|
||
|
|
`brush` targets compatibility with **`bash` 5.3+**. Behavior may differ from older `bash` versions (3.x, 4.x) in some areas.
|
||
|
|
|
||
|
|
## Reporting Compatibility Issues
|
||
|
|
|
||
|
|
Found a script that works in `bash` but not in `brush`?
|
||
|
|
|
||
|
|
1. **Check existing issues:** [GitHub Issues](https://github.com/reubeno/brush/issues)
|
||
|
|
2. **Create a minimal reproducer:** Reduce to the smallest failing script
|
||
|
|
3. **File an issue** with:
|
||
|
|
- The script or command that fails
|
||
|
|
- Expected behavior (what `bash` does)
|
||
|
|
- Actual behavior (what `brush` does)
|
||
|
|
- Your platform (Linux/macOS/etc.)
|
||
|
|
|
||
|
|
## Tracking Progress
|
||
|
|
|
||
|
|
- **GitHub Issues:** Track specific compatibility work
|
||
|
|
- **Test Suite:** 1700+ tests run on every PR
|
||
|
|
- **This Document:** Updated as features are implemented
|
||
|
|
|
||
|
|
## Related Resources
|
||
|
|
|
||
|
|
- [`bash` Reference Manual](https://www.gnu.org/software/bash/manual/)
|
||
|
|
- [POSIX Shell Specification](https://pubs.opengroup.org/onlinepubs/9699919799/)
|
||
|
|
- [`brush` Test Cases](https://github.com/reubeno/brush/tree/main/brush-shell/tests/cases)
|