https://github.com/rash-sh/rash
Declarative shell scripting using Rust native bindings inspired by Ansible
https://github.com/rash-sh/rash
bash cli cloud containers docker rust shell
Last synced: about 2 months ago
JSON representation
Declarative shell scripting using Rust native bindings inspired by Ansible
- Host: GitHub
- URL: https://github.com/rash-sh/rash
- Owner: rash-sh
- License: gpl-3.0
- Created: 2020-05-05T19:35:09.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2025-05-11T22:01:13.000Z (2 months ago)
- Last Synced: 2025-05-13T11:15:12.815Z (2 months ago)
- Topics: bash, cli, cloud, containers, docker, rust, shell
- Language: Rust
- Homepage: https://rash-sh.github.io
- Size: 1.33 MB
- Stars: 218
- Watchers: 11
- Forks: 9
- Open Issues: 27
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# rash

[](https://docs.rs/rash_core)
[](https://crates.io/crates/rash_core)
[](https://mind42.com/mindmap/f299679e-8dc5-48d8-b0f0-4d65235cdf56)

[](https://aur.archlinux.org/packages/rash)Rash is a lightweight, container-friendly shell scripting language that uses a declarative YAML syntax inspired by [Ansible](https://www.ansible.com/). It brings the simplicity and readability of Ansible playbooks to local scripting and container entrypoints, all in a single Rust binary with no dependencies.
## Why Rash?
- **Declarative vs Imperative**: Define what your script should accomplish, not how
- **Container-Optimized**: Single binary with no dependencies, perfect for minimal containers
- **Lightweight**: Runs on any Linux system, even resource-constrained IoT devices
- **Template-Powered**: Uses [MiniJinja](https://github.com/mitsuhiko/minijinja) for powerful templating capabilities
- **Intuitive Syntax**: Familiar YAML structure for those who know Ansible
- **Built-in Command-Line Parsing**: Elegant [docopt](http://docopt.org) implementation for clean script interfaces
- **Modular Design**: Focused modules for different tasks## Example: Imperative vs Declarative
### Bash (Imperative)
```bash
#!/bin/bash
set -e# Validate required environment variables
REQUIRED_PARAMS="
DATABASE_URL
DATABASE_USER
DATABASE_PASSWORD
LOG_LEVEL
"for required in $REQUIRED_PARAMS ; do
[[ -z "${!required}" ]] && echo "$required IS NOT DEFINED" && exit 1
done# Configure the application
echo "[$0] Configuring application..."
CONFIG_FILE="/app/config.json"
cat > $CONFIG_FILE << EOF
{
"database": {
"url": "$DATABASE_URL",
"user": "$DATABASE_USER",
"password": "$DATABASE_PASSWORD"
},
"server": {
"port": "${SERVER_PORT:-8080}",
"log_level": "$LOG_LEVEL"
}
}
EOF# Set correct permissions
chmod 0600 $CONFIG_FILEecho "[$0] Starting application..."
exec "$@"
```### Rash (Declarative)
```yaml
#!/usr/bin/env rash- name: Verify input parameters
assert:
that:
- env.DATABASE_URL is defined
- env.DATABASE_USER is defined
- env.DATABASE_PASSWORD is defined
- env.LOG_LEVEL is defined- name: Configure application
template:
src: config.j2
dest: /app/config.json
mode: "0600"
vars:
server_port: "{{ env.SERVER_PORT | default('8080') }}"- name: Launch command
command:
cmd: "{{ rash.argv }}"
transfer_pid: yes
```## Installation
### Binary (Linux/macOS)
```bash
curl -s https://api.github.com/repos/rash-sh/rash/releases/latest \
| grep browser_download_url \
| grep -v sha256 \
| grep $(uname -m) \
| grep $(uname | tr '[:upper:]' '[:lower:]') \
| grep -v musl \
| cut -d '"' -f 4 \
| xargs curl -s -L \
| sudo tar xvz -C /usr/local/bin
```### Arch Linux (AUR)
```bash
yay -S rash
```### Cargo
```bash
cargo install rash_core
```### Docker
```bash
docker run --rm -v /usr/local/bin/:/output --entrypoint /bin/cp ghcr.io/rash-sh/rash:latest /bin/rash /output/
```## Key Features
### Built-in Command-Line Interface Parser
```yaml
#!/usr/bin/env -S rash --
#
# Copy files from source to dest dir
#
# Usage:
# copy.rh [options] ...
# copy.rh
#
# Options:
# -h --help show this help message and exit
# --mode MODE dest file permissions [default: 0644]- copy:
src: "{{ item }}"
dest: "{{ dest }}/{{ item | split('/') | last }}"
mode: "{{ options.mode }}"
loop: "{{ source | default([]) }}"
```### Container Entrypoints
Perfect for creating maintainable container entrypoints that handle environment validation, configuration management, and service initialization:
```dockerfile
FROM alpine:3.16# Install rash binary
ADD https://github.com/rash-sh/rash/releases/download/v0.6.0/rash-x86_64-unknown-linux-musl.tar.gz /tmp/
RUN tar xvzf /tmp/rash-x86_64-unknown-linux-musl.tar.gz -C /usr/local/bin && \
rm /tmp/rash-x86_64-unknown-linux-musl.tar.gz# Add entrypoint script
COPY entrypoint.rh /entrypoint.rh
RUN chmod +x /entrypoint.rhENTRYPOINT ["/entrypoint.rh"]
```### Templating System
Access environment variables and use powerful filters:
```yaml
- name: Configure application
template:
src: config.j2
dest: /etc/app/config.json
vars:
app_port: "{{ env.PORT | default('8080') }}"
app_log_level: "{{ env.LOG_LEVEL | default('info') }}"
database_url: "{{ env.DATABASE_URL }}"
```### Privilege Escalation
Run commands as different users with the built-in `become` functionality:
```yaml
- name: Configure system DNS
become: true
copy:
dest: /etc/resolv.conf
content: |
nameserver 208.67.222.222
nameserver 208.67.220.220
```## Documentation
For comprehensive documentation, visit:
[https://rash-sh.github.io/docs/rash/master/](https://rash-sh.github.io/docs/rash/master/)## Community
- GitHub: [https://github.com/rash-sh/rash](https://github.com/rash-sh/rash)
- Report Issues: [https://github.com/rash-sh/rash/issues](https://github.com/rash-sh/rash/issues)## License
Rash is distributed under the [GPL-3.0 License](https://github.com/rash-sh/rash/blob/master/LICENSE).