| Crates.io | rush-sh |
| lib.rs | rush-sh |
| version | 0.3.2 |
| created_at | 2025-09-12 05:39:44.159857+00 |
| updated_at | 2025-09-13 08:00:27.147266+00 |
| description | A POSIX sh-compatible shell written in Rust |
| homepage | |
| repository | https://github.com/drewwalton19216801/rush-sh |
| max_upload_size | |
| id | 1835218 |
| size | 1,887,531 |
Rush is a POSIX sh-compatible shell implemented in Rust. It provides both interactive mode with a REPL prompt and script mode for executing commands from files. The shell supports basic shell features like command execution, pipes, redirections, environment variables, and built-in commands.
alias hurry='rush -c "do the thing"'—because sometimes you just need to rush to judgment.| operator.<) and output (>, >>) redirections.$(command) syntax: echo "Current dir: $(pwd)"`command` syntax: echo "Files: ls | wc -l"echo $(echo $HOME)VAR=value and VAR="quoted value"$VAR and special variables ($?, $$, $0)export VAR and export VAR=valueif statements: if condition; then commands; elif condition; then commands; else commands; ficase statements with glob pattern matching: case word in pattern1|pattern2) commands ;; *.txt) commands ;; *) default ;; esaccd: Change directoryexit: Exit the shellpwd: Print working directoryenv: List environment variablesexport: Export variables to child processesunset: Remove variablessource / .: Execute a script file with rush (bypasses shebang and comment lines)pushd: Push directory onto stack and change to itpopd: Pop directory from stack and change to itdirs: Display directory stackalias: Define or display aliasesunalias: Remove alias definitionstest / [: POSIX-compatible test builtin with string and file testsset_colors: Enable/disable color output dynamicallyset_color_scheme: Switch between color themes (default/dark/light)help: Show available commands~/.rushrc on interactive shell startupsrc/, ../, /usr/bin/)~/ and ~/Documents/ pathsRush now provides comprehensive environment variable support with full POSIX compliance:
Variable Assignment: Support for both simple and quoted assignments
MY_VAR=hello
MY_VAR="hello world"
NAME="Alice"
Variable Expansion: Expand variables in commands with $VAR syntax
echo "Hello $NAME"
echo "Current directory: $PWD"
Special Variables: Built-in support for special shell variables
echo "Last exit code: $?"
echo "Shell PID: $$"
echo "Script name: $0"
Export Mechanism: Export variables to child processes
export MY_VAR
export NEW_VAR=value
Variable Management: Full lifecycle management with unset
unset MY_VAR
Multi-Mode Support: Variables work consistently across all execution modes
-c command stringsExample usage:
# Set and use variables
MY_VAR="Hello from Rush"
echo "Message: $MY_VAR"
# Export to child processes
export MY_VAR
env | grep MY_VAR
# Use in pipelines
echo "$MY_VAR" | grep "Rush"
# Special variables
if true; then echo "Success ($?)"; fi
Rush now supports advanced case statements with full glob pattern matching capabilities:
* (any characters), ? (single character), and [abc] (character classes)| (e.g., *.txt|*.md)glob crateExample usage:
case $filename in
*.txt|*.md) echo "Text file" ;;
*.jpg|*.png) echo "Image file" ;;
file?) echo "Single character file" ;;
[abc]*) echo "Starts with a, b, or c" ;;
*) echo "Other file type" ;;
esac
Rush now supports directory stack management with the classic Unix pushd, popd, and dirs commands:
pushd <directory>: Changes to the specified directory and pushes the current directory onto the stackpopd: Pops the top directory from the stack and changes to itdirs: Displays the current directory stackExample usage:
# Start in home directory
pwd
# /home/user
# Push to /tmp and see stack
pushd /tmp
# /tmp /home/user
# Push to another directory
pushd /var
# /var /tmp /home/user
# See current stack
dirs
# /var /tmp /home/user
# Pop back to /tmp
popd
# /tmp /home/user
# Pop back to home
popd
# /home/user
This feature is particularly useful for:
Rush now supports comprehensive command substitution with both $(...) and `...` syntax:
$(command) and `command` work identicallyExample usage:
Rush now displays a condensed version of the current working directory in the interactive prompt:
Example prompt displays:
/h/d/p/r/rush $
/u/b/s/project $
/h/u/Documents $
This feature provides context about your current location while keeping the prompt concise.
# Basic command substitution
echo "Current directory: $(pwd)"
echo "Files in directory: `ls | wc -l`"
# Variable assignments with substitutions
PROJECT_DIR="$(pwd)/src"
FILE_COUNT="$(ls *.rs 2>/dev/null | wc -l)"
# Complex expressions
echo "Rust version: $(rustc --version | cut -d' ' -f2)"
echo "Files modified today: $(find . -name '*.rs' -mtime -1 | wc -l)"
# Error handling
NONEXISTENT="$(nonexistent_command 2>/dev/null || echo 'command failed')"
echo "Result: $NONEXISTENT"
# Multiple commands
echo "Combined output: $(echo 'Hello'; echo 'World')"
Command substitution works seamlessly with:
$(echo hello | grep ll) > output.txtecho $(echo $HOME)echo "Path: $(pwd)"$(find . -name "*.rs" -exec wc -l {} \;)Rush now provides comprehensive built-in alias support, allowing you to create shortcuts for frequently used commands:
alias name=value syntaxalias commandalias nameunalias nameExample usage:
# Create aliases
alias ll='ls -l'
alias la='ls -la'
alias ..='cd ..'
alias grep='grep --color=auto'
# List all aliases
alias
# Output:
# alias ll='ls -l'
# alias la='ls -la'
# alias ..='cd ..'
# alias grep='grep --color=auto'
# Show specific alias
alias ll
# Output: alias ll='ls -l'
# Use aliases (they expand automatically)
ll
la /tmp
..
# Remove aliases
unalias ll
alias # ll is no longer listed
# Error handling
unalias nonexistent # Shows: unalias: nonexistent: not found
Key Features:
Advanced Usage:
# Complex aliases with pipes and redirections
alias backup='cp -r ~/Documents ~/Documents.backup && echo "Backup completed"'
alias count='find . -name "*.rs" | wc -l'
# Aliases with variables (expanded at definition time)
MY_DIR="/tmp"
alias cleanup="rm -rf $MY_DIR/*"
# Function-like aliases
alias mkcd='mkdir -p "$1" && cd "$1"' # Note: $1 won't work as expected
Implementation Details:
Rush now provides comprehensive support for the POSIX test builtin command and its [ bracket syntax, enabling powerful conditional logic in shell scripts:
-z) or non-empty (-n)-e), regular files (-f), and directories (-d)test and [ syntax work identicallyExample usage:
# String tests
if test -z ""; then echo "Empty string"; fi
if [ -n "hello" ]; then echo "Non-empty string"; fi
# File tests
if test -e "/tmp/file.txt"; then echo "File exists"; fi
if [ -d "/tmp" ]; then echo "Is directory"; fi
if test -f "/etc/passwd"; then echo "Is regular file"; fi
# Complex conditions
if [ -n "$MY_VAR" ] && test -e "$CONFIG_FILE"; then
echo "Variable set and config file exists"
fi
# Error handling
test -x "invalid_option" # Returns exit code 2
exit_code=$?
if [ $exit_code -eq 2 ]; then echo "Invalid option used"; fi
Key Features:
-z (zero length) and -n (non-zero length) tests-e (exists), -f (regular file), -d (directory)[ condition ] works identically to test conditionAdvanced Usage:
# Variable existence checks
MY_VAR="hello world"
if test -n "$MY_VAR"; then
echo "MY_VAR is set to: $MY_VAR"
fi
# Safe file operations
TARGET_FILE="/tmp/safe_file.txt"
if test -e "$TARGET_FILE"; then
echo "File exists, backing up..."
mv "$TARGET_FILE" "$TARGET_FILE.backup"
fi
# Directory creation with checks
TARGET_DIR="/tmp/test_dir"
if test -d "$TARGET_DIR"; then
echo "Directory already exists"
else
mkdir -p "$TARGET_DIR"
echo "Directory created"
fi
The test builtin is fully integrated with Rush's control structures, enabling complex conditional logic in scripts while maintaining POSIX compatibility.
Rush now provides comprehensive color support for enhanced terminal output with automatic detection and flexible configuration:
NO_COLOR=1 (accessibility standard) and RUSH_COLORS (explicit control)help, pwd, env with contextual coloringset_colors and set_color_scheme builtinsExample usage:
# Enable colors explicitly
export RUSH_COLORS=on
# Disable colors for accessibility
export NO_COLOR=1
# Switch color schemes
set_color_scheme dark
set_color_scheme light
set_color_scheme default
# Control colors dynamically
set_colors on
set_colors off
set_colors status # Show current status
Key Features:
NO_COLOR=1 environment variable for users who prefer monochrome outputRUSH_COLORS variable supports auto, on, off, 1, 0, true, false valuesColor Schemes:
Configuration Options:
# Environment variables
export NO_COLOR=1 # Disable colors (accessibility)
export RUSH_COLORS=auto # Auto-detect (default)
export RUSH_COLORS=on # Force enable
export RUSH_COLORS=off # Force disable
# Runtime commands
set_colors on # Enable colors
set_colors off # Disable colors
set_colors status # Show current status
set_color_scheme default # Standard colors
set_color_scheme dark # Dark theme
set_color_scheme light # Light theme
The color system is designed to be both powerful and unobtrusive, providing visual enhancements while respecting user preferences and accessibility needs.
Rush automatically sources a configuration file ~/.rushrc when starting in interactive mode, similar to bash's .bashrc. This allows you to customize your shell environment with:
Example ~/.rushrc file:
# Set environment variables
export EDITOR=vim
export PATH="$HOME/bin:$PATH"
# Create useful aliases
alias ll='ls -la'
alias ..='cd ..'
alias grep='grep --color=auto'
# Set custom variables
MY_PROJECTS="$HOME/projects"
WORKSPACE="$HOME/workspace"
# Display welcome message
echo "Welcome to Rush shell!"
echo "Type 'help' for available commands."
Key Features:
.rushrc files don't prevent shell startup.rushrc are available throughout the session.rushrc are handled gracefully~/.rushrc following Unix conventionsUsage Notes:
.rushrc are available to all subsequent commandsexport to make variables available to child processes#) are ignoredInstall rush-sh from crates.io:
cargo install rush-sh
Clone the repository:
git clone https://github.com/drewwalton19216801/rush-sh.git
cd rush-sh
Build the project:
cargo build --release
The binary will be available at target/release/rush-sh.
Run the shell without arguments to enter interactive mode:
./target/release/rush-sh
or
rush-sh
You'll see a prompt showing the condensed current working directory followed by $ (e.g., /h/d/p/r/rush-sh $ ) where you can type commands. Type exit to quit.
Configuration: Rush automatically sources ~/.rushrc on startup if it exists, allowing you to set up aliases, environment variables, and other customizations.
Execute commands from a file:
./target/release/rush-sh script.sh
or
rush-sh script.sh
The shell will read and execute each line from the script file. Note that when using script mode, shebang lines (e.g., #!/usr/bin/env bash) are not bypassed - they are executed as regular comments.
Execute a command string directly:
./target/release/rush-sh -c "echo Hello World"
or
rush-sh -c "echo Hello World"
The shell will execute the provided command string and exit.
The source (or .) built-in command provides a way to execute script files while bypassing shebang lines and comment lines that may specify other shells:
source script.sh
. script.sh
This is particularly useful for:
#!/usr/bin/env rush-sh shebangs#!/usr/bin/env bash) using rush insteadUnlike script mode (running ./target/release/rush-sh script.sh), the source command automatically skips shebang lines and comment lines, and executes all commands using the rush interpreter. Variables set in the sourced script are available in the parent shell.
ls -lals | grep txtecho "Hello" > hello.txtcd /tmppwdpushd /tmppopddirssource script.sh. script.shsource examples/basic_commands.shsource examples/elif_example.shsource examples/case_example.shsource examples/variables_example.shsource examples/complex_example.shalias ll='ls -l'; alias la='ls -la'aliasalias llunalias llll /tmpMY_VAR=hello; echo $MY_VARexport MY_VAR=value; env | grep MY_VARecho "Exit code: $?"; echo "PID: $$"NAME="John Doe"; echo "Hello $NAME"if true; then echo yes; else echo no; fiif false; then echo no; elif true; then echo yes; else echo maybe; ficase hello in hello) echo match ;; *) echo no match ;; esaccase file.txt in *.txt) echo "Text file" ;; *.jpg) echo "Image" ;; *) echo "Other" ;; esaccase file in *.txt|*.md) echo "Document" ;; *.exe|*.bin) echo "Executable" ;; *) echo "Other" ;; esaccase letter in [abc]) echo "A, B, or C" ;; *) echo "Other letter" ;; esacif test -z "$VAR"; then echo "Variable is empty"; fiif [ -f "/etc/passwd" ]; then echo "File exists"; fiif test -n "$NAME" && [ -d "/tmp" ]; then echo "Ready"; fitest -x "invalid"; echo "Exit code: $?"echo "Current dir: $(pwd)"echo "Files: ls | wc -l"PROJECT_DIR="$(pwd)/src"echo "Rust version: $(rustc --version | cut -d' ' -f2)"RESULT="$(nonexistent_command 2>/dev/null || echo 'failed')"$(echo hello | grep ll) > output.txtecho "Output: $(echo 'First'; echo 'Second')"cd → cd , env , exit cat f → cat file.txt cd src/ → cd src/main/l → ls , g → grep ls src/m → ls src/main/Rush consists of the following components:
$(...) and `...` syntax), and alias expansion.$?, $$, $0), current directory, directory stack, and command aliases.export, unset, env) and alias management (alias, unalias).rustyline: For interactive line editing and history.signal-hook: For robust signal handling.nix: For Unix system interactions.libc: For low-level C library bindings.glob: For pattern matching in case statements.Rush includes a comprehensive test suite to ensure reliability and correctness. The tests cover unit testing for individual components, integration testing for end-to-end functionality, and error handling scenarios.
Run all tests with:
cargo test
Run specific test modules:
cargo test builtins
cargo test completion
cargo test executor
cargo test lexer
cargo test main
cargo test parser
cargo test state
cargo test integration
The test suite provides extensive coverage of:
$(...) and `...` syntax, error handling, variable expansion)Contributions are welcome! Please fork the repository, make your changes, and submit a pull request.
This project is licensed under the MIT License. See LICENSE.txt for details.