What huck supports

huck implements most of bash's surface — syntax, expansions, control flow, arrays, job control, line editing, and completion — and checks every one of these against real bash output.

Command syntax & operators

Simple commands and pipelines (a | b); lists with ;, &&, ||, and & (background, including backgrounding an and-or group); grouping with ( … ) (subshell) and { …; } (current shell); redirections <, >, >>, >|, 2>, 2>>, &>, fd duplication (2>&1), here-documents (<<, <<-), and here-strings (<<<) — including redirections on compound commands. Comments, line continuation, and multi-line input all work the way bash does.

mkdir -p dist && cp *.rs dist/ || echo "nothing to copy"
cat <<EOF > dist/notes.txt
built at $(date +%F)
EOF
wc -l < dist/notes.txt

Expansions

Parameter expansion ($VAR, ${VAR}, positional and special parameters), the full modifier set (${v:-w}, prefix/suffix strip, substring, pattern substitution, case modification, @Q/@P/@U transforms, indirection), arithmetic $((…)), command substitution $(…) and `…`, brace expansion, tilde expansion, and pathname globbing including POSIX classes and extglob.

name=world
echo "${name^} says: ${name:0:3}"
echo {1..5}
echo $((2**10))

Control flow & functions

if/elif/else, while/until, for (word-list, "$@", and C-style), select, and case (with ;;/;&/;;&); break N/continue N. Functions in both name() { … } and function name { … } form, with positional args, local, return, and dynamic scoping. The [[ … ]] extended test supports glob and regex matching (=~, populating BASH_REMATCH).

greet() {
  local who=${1:-world}
  echo "hello, $who"
}
greet huck

Variables & arrays

Scalars, indexed arrays (a=(x y), a[i]=, a+=, slicing), and associative arrays (declare -A), with integer (-i), readonly (-r), and export (-x) attributes, declare -g, and printf -v.

declare -A colors=([sky]=blue [grass]=green)
for k in "${!colors[@]}"; do
  echo "$k -> ${colors[$k]}"
done

Job control

Foreground and background process groups with tcsetpgrp terminal handoff — so vim, less, and Ctrl-Z work — SIGCHLD reaping with [N] Done notices, and the full jobs/fg/bg/wait/kill/disown toolkit with %N/%+/%%/%-/%cmd job specifiers.

huck> sleep 30 &
[1] 20481
huck> jobs
[1]+ Running sleep 30 &
huck> fg %1
sleep 30
sleep 30 &
job_pid=$!
kill "$job_pid"
wait "$job_pid" 2>/dev/null
echo "job $job_pid stopped"

Line editing, history & completion

A line editor with history persisted to $HISTFILE, history expansion (!!, !n, !str, !$, ^old^new^), and programmable tab completion: command/file/variable completion plus the full complete/compgen/compopt machinery, which drives the system bash-completion framework.

huck> echo building the site
building the site
huck> !!
echo building the site
building the site
huck> ehco deploying the site
huck: ehco: command not found
huck> ^ehco^echo^
echo deploying the site
deploying the site

Builtins & options

cd, pwd, echo, printf (incl. %q), read, test/[, [[, export, readonly, local, declare/typeset, unset, set (-e/-u/-x/-f/-o pipefail/-C), shopt, getopts, eval, command, hash, trap (EXIT/ERR/DEBUG/RETURN + signals), alias/unalias, job-control builtins, history, break, continue, return, exit, and complete/compgen/compopt.

set -e
trap 'echo "cleaning up"' EXIT
declare -ri max=10
getopts ":v" opt || true
echo "max is $max"

Verified against bash

Every feature ships with a design spec, an implementation plan, a test suite, and a byte-identical bash-diff harness under tests/scripts/*_diff_check.sh: the same shell fragment runs through both bash and huck, and the harness asserts the two outputs are byte-for-byte identical. As of this writing that's around 3,400 unit/integration tests and 160 bash-diff harnesses, all green.

# tests/scripts/expansion_diff_check.sh (shape)
frag='name=world; echo "${name^} says: ${name:0:3}"; echo {1..5}; echo $((2**10))'
diff <(bash -c "$frag") <(huck -c "$frag") && echo "byte-identical"