7. Shell Integration
Lash is built for shell scripts. It supports many Bash features directly, but it still parses known Lash syntax first.
Bare shell commands
Most shell-like lines that are not recognized as Lash statements become raw command statements:
set -euo pipefail
shopt -s nullglob
export RELEASE_CHANNEL=stable
source ./env.sh
echo "building..."
The compiler recognizes common shell builtins such as set, export, shopt, alias, source, ., unset, declare, and local for validation and warnings.
Known Lash statement prefixes such as if, for, var, let, return, trap, and wait are parsed as Lash syntax.
sh statements
Use sh "..." when you want to force a string literal to be emitted as shell code.
sh "printf '%s\n' \"$HOME\""
The payload must be a string literal. This restriction keeps Bash code generation predictable.
Command substitution
let branch = $(git rev-parse --abbrev-ref HEAD)
echo $"branch={branch}"
Lash preserves Bash command substitution syntax by rewriting it internally before parsing.
Interpolated command segments are supported:
let dist = "./dist"
let archives = $(find $"\"{dist}\" -maxdepth 1 -name '*.tar.gz'")
test captures
let path = ".git"
let has_git = $(test $"-d \"{path}\"")
if has_git == 1
echo "repo"
end
$(test "...") lowers to a Bash [[ ... ]] check that echoes 1 or 0. The test payload must be a string literal.
Array spread in shell payloads
Inside shell payload strings, $name... expands a Lash array variable as Bash "${name[@]}".
let files = ["a.txt", "b.txt"]
sh "printf '%s\n' $files..."
Process substitution
diff <(sort left.txt) <(sort right.txt)
Input process substitution <(...) and output process substitution >(...) are supported and lower back to Bash process substitution.
Redirects
Redirect expressions are supported as standalone expression statements.
echo "log" > "build.log"
echo "more" >> "build.log"
echo "error" 2> "error.log"
echo "all" &> "combined.log"
cat < "input.txt"
exec <> "state.db"
Supported redirect operators:
>stdout truncate>>stdout append2>stderr truncate2>>stderr append&>stdout and stderr truncate&>>stdout and stderr append<stdin from file<>read/write filen>&mduplicate file descriptorn>&-close file descriptor
Here input
cat << "one line"
cat << [[line one
line two]]
cat <<- [[ line with leading tab
next line]]
Single-line << string payloads lower to Bash here-strings. Multiline literals lower to heredocs. <<- requires a multiline string literal and lowers to a tab-stripping heredoc.
The deprecated Bash spelling <<< is not the Lash syntax. Use <<.