A transpiler that converts Bash scripts into Amber — a modern, type-safe language that compiles back to shell.
cargo install --path .# Print Amber output to stdout
bash2amber script.sh
# Write Amber output to a file
bash2amber script.sh script.abname="World"
echo "Hello $name"let name = "World"
echo("Hello {name}")
groceries=("apple" "banana" "cherry")
for item in "${groceries[@]}"; do
echo "$item"
donelet groceries = ["apple", "banana", "cherry"]
for item in groceries {
echo(item)
}
for (( i=0; i<=5; i++ )); do
echo "$i"
donefor i in 0..=5 {
echo(i)
}
status="200"
if [ "$status" == "200" ]; then
echo "UP"
else
echo "DOWN"
filet status_var = "200"
if status_var == "200" {
echo("UP")
} else {
echo("DOWN")
}
Case blocks are converted into if-chains.
fruit="pear"
case "$fruit" in
apple|banana)
echo "common"
;;
pear)
echo "pear"
;;
esaclet fruit = "pear"
if {
fruit == "apple" or fruit == "banana" {
echo("common")
}
fruit == "pear" {
echo("pear")
}
}
base=10
result=$((base + 4 / 2))
echo "$result"let base = 10
let result = base + 4 / 2
echo(result)
Annotate your Bash functions with ## fundoc comments to get typed Amber output.
## (msg: Text): Text(output)
wrap() {
local msg="$1"
output="[${msg}]"
}
wrap "hello"
echo $outputfun wrap(msg: Text): Text {
return "[{msg}]"
}
let output = wrap("hello")
echo(output)
Simple if/else assignments are collapsed into ternary form.
mode="prod"
if [ "$mode" = "prod" ]; then
status="live"
else
status="test"
fi
echo "$status"let mode = "prod"
let status_var = mode == "prod" then "live" else "test"
echo(status_var)
When bash2amber encounters a construct it can't convert, it wraps the original shell code in a trust block so the output still compiles:
trust $ original-command $