| Crates.io | bashrs |
| lib.rs | bashrs |
| version | 0.3.3 |
| created_at | 2025-07-07 16:31:37.763566+00 |
| updated_at | 2025-07-07 16:36:26.620029+00 |
| description | Rust-to-Shell transpiler for deterministic bootstrap scripts |
| homepage | https://github.com/paiml/bashrs |
| repository | https://github.com/paiml/bashrs |
| max_upload_size | |
| id | 1741536 |
| size | 795,299 |
Rash transpiles a safe subset of Rust to POSIX-compliant shell scripts, enabling you to write maintainable and type-safe shell scripts using familiar Rust syntax.
Write Rust:
// install.rs
#[rash::main]
fn main() {
let version = env_var_or("VERSION", "1.0.0");
let prefix = env_var_or("PREFIX", "/usr/local");
echo("Installing MyApp {version} to {prefix}");
// Create installation directories
mkdir_p("{prefix}/bin");
mkdir_p("{prefix}/share/myapp");
// Copy files (with automatic quoting)
if exec("cp myapp {prefix}/bin/") {
echo("✓ Binary installed");
} else {
echo("✗ Failed to install binary");
exit(1);
}
}
Get POSIX shell:
$ bashrs build install.rs -o install.sh
$ cat install.sh
#!/bin/sh
# Generated by Rash v0.3.1
# POSIX-compliant shell script
set -euf
IFS='
'
export LC_ALL=C
# Rash runtime functions
rash_require() {
if ! "$@"; then
echo "FATAL: Requirement failed: $*" >&2
exit 1
fi
}
# Main script begins
main() {
VERSION="${VERSION:-1.0.0}"
PREFIX="${PREFIX:-/usr/local}"
echo "Installing MyApp $VERSION to $PREFIX"
mkdir -p "$PREFIX/bin"
mkdir -p "$PREFIX/share/myapp"
if cp myapp "$PREFIX/bin/"; then
echo "✓ Binary installed"
else
echo "✗ Failed to install binary"
exit 1
fi
}
# Execute main function
main "$@"
cargo install bashrs
Pre-built binaries are available for Linux and macOS:
# Linux x86_64
curl -L https://github.com/paiml/bashrs/releases/latest/download/bashrs-x86_64-unknown-linux-musl.tar.gz | tar xz
# macOS x86_64
curl -L https://github.com/paiml/bashrs/releases/latest/download/bashrs-x86_64-apple-darwin.tar.gz | tar xz
# macOS ARM64
curl -L https://github.com/paiml/bashrs/releases/latest/download/bashrs-aarch64-apple-darwin.tar.gz | tar xz
cargo binstall bashrs
# Full build with all features
cargo install --git https://github.com/paiml/bashrs
# Minimal build (smaller binary, ~2MB)
cargo install --git https://github.com/paiml/bashrs --no-default-features --features minimal
# Transpile a Rust file to shell
bashrs build input.rs -o output.sh
# Check if a file is valid Rash
bashrs check input.rs
# Verify safety properties
bashrs verify input.rs --verify strict
# Start interactive playground (if built with playground feature)
bashrs playground
USAGE:
bashrs [OPTIONS] <COMMAND>
COMMANDS:
build Transpile Rust to shell script
check Validate Rust source without transpiling
verify Run formal verification
inspect Analyze AST and safety properties
playground Interactive development environment (requires feature)
OPTIONS:
-v, --verbose Enable verbose output
-V, --version Print version information
-h, --help Print help information
BUILD OPTIONS:
-o, --output <FILE> Output file (default: stdout)
-O, --optimize <LEVEL> Optimization level: none, size, readability (default: readability)
-t, --target <SHELL> Target shell: posix, bash, ash (default: posix)
--verify <LEVEL> Verification level: none, basic, strict, paranoid
Rash supports a carefully chosen subset of Rust that maps cleanly to shell:
let name = "Alice"; // String literals
let count = 42; // Integers
let flag = true; // Booleans
let user = env("USER"); // Environment variables
let result = capture("date"); // Command output
// I/O operations
echo("Hello, World!"); // Print to stdout
eprint("Error!"); // Print to stderr
// File system
mkdir_p("/tmp/myapp"); // Create directory recursively
write_file("config.txt", data); // Write file
let content = read_file("config.txt"); // Read file
if path_exists("/etc/config") { ... } // Check path
// Process management
exec("ls -la"); // Run command
let output = capture("date"); // Capture command output
exit(0); // Exit with code
// Environment
set_env("KEY", "value"); // Set environment variable
let val = env("KEY"); // Get environment variable
let val = env_var_or("KEY", "default"); // With default
// Conditionals
if condition {
// ...
} else if other {
// ...
} else {
// ...
}
// Pattern matching (limited)
match value {
"linux" => echo("Linux detected"),
"darwin" => echo("macOS detected"),
_ => echo("Unknown OS"),
}
loops feature)// Bounded iteration only
for i in 0..10 {
echo("Iteration: {i}");
}
// While loops must have explicit bounds
let mut count = 0;
while count < 10 {
count = count + 1;
}
All generated scripts are protected against:
set -u catches undefined varsExample of automatic safety:
let user_input = env("UNTRUSTED");
exec("echo {user_input}"); // Safe: becomes echo "$user_input"
See the examples/ directory for complete examples:
Basic
Control Flow
Safety
Real-World
Generated scripts are tested on:
| Shell | Version | Status |
|---|---|---|
| POSIX sh | - | ✅ Full support |
| dash | 0.5.11+ | ✅ Full support |
| bash | 3.2+ | ✅ Full support |
| ash (BusyBox) | 1.30+ | ✅ Full support |
| zsh | 5.0+ | ✅ Full support |
| mksh | R59+ | ✅ Full support |
Rash is designed for fast transpilation:
We welcome contributions! Please see our Contributing Guide for details.
# Clone the repository
git clone https://github.com/paiml/rash.git
cd rash
# Run tests
make test
# Run with all checks
make validate
# Build release binary
make release
Rash is licensed under the MIT License. See LICENSE for details.
Rash is built with safety principles inspired by: