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.
- 🛡️ Safety First: Automatic protection against shell injection attacks
- 🔍 Compile-Time Verification: Catch errors before deployment
- 📦 Zero Runtime Dependencies: Generated scripts work on any POSIX shell
- 🎯 Deterministic Output: Same input always produces identical scripts
- ✅ ShellCheck Compliant: All output passes strict linting
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"),
}
// 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:
- Command Injection: All variables are properly quoted
- Path Traversal: Paths are validated and escaped
- Glob Expansion: Glob patterns are quoted when needed
- Word Splitting: IFS is set to safe value
- Undefined Variables:
set -u
catches undefined vars
Example 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
- Hello World - Simplest example
- Variables - Variable usage and escaping
- Functions - Built-in functions
-
Control Flow
- Conditionals - If/else statements
- Loops - Bounded iteration
-
Safety
- Injection Prevention - Security examples
- String Escaping - Special character handling
-
Real-World
- Minimal Installer - Bootstrap script
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:
- Typical scripts transpile in <10ms
- Memory usage <10MB for most scripts
- Generated scripts add minimal overhead (~20 lines boilerplate)
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:
- ShellCheck for shell script analysis
- Oil Shell for shell language design
- The Rust community for memory safety practices
- Core transpilation engine
- Basic safety validation
- ShellCheck compliance
- Property-based testing
- Language server (LSP)
- Incremental compilation
- More shell targets (fish, PowerShell)
- Package manager integration