Rush - A Unix shell written in Rust
Version 0.3.4 - A comprehensive POSIX sh-compatible shell implementation

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.
Pun-der the Hood
- In a hurry? Don’t bash your head against it—Rush it.
- When your pipelines need a drum solo, put them on Rush and let the commands Neil-Peart through.
- Tom Sawyer tip: chores go faster when you make them look like a Rush job; no need to paint the fence by hand when the shell can whitewash it with a one-liner.
- Alias your productivity:
alias hurry='rush -c "do the thing"'—because sometimes you just need to rush to judgment. - This shell doesn’t just run fast; it gives you the Rush of a clean exit status.
Features
- Command Execution: Execute external commands and built-in commands.
- Pipes: Chain commands using the
|operator. - Redirections: Input (
<) and output (>,>>) redirections. - Command Substitution: Execute commands and substitute their output inline.
$(command)syntax:echo "Current dir: $(pwd)"`command`syntax:echo "Files:ls | wc -l"- Variable expansion within substitutions:
echo $(echo $HOME) - Error handling with fallback to literal syntax
- Arithmetic Expansion: Evaluate mathematical expressions using
$((...))syntax.- Basic arithmetic:
echo $((2 + 3 * 4)) - Variable integration:
result=$((x * y + z)) - Comparison operations:
$((5 > 3))returns 1 (true) or 0 (false) - Bitwise and logical operations:
$((5 & 3)),$((x && y)) - Operator precedence with parentheses support
- Basic arithmetic:
- Environment Variables: Full support for variable assignment, expansion, and export.
- Variable assignment:
VAR=valueandVAR="quoted value" - Variable expansion:
$VARand special variables ($?,$$,$0) - Parameter Expansion with Modifiers: Advanced variable expansion with POSIX sh modifiers
${VAR:-default}- use default if VAR is unset or null${VAR:=default}- assign default if VAR is unset or null${VAR:+replacement}- use replacement if VAR is set and not null${VAR:?error}- display error if VAR is unset or null${VAR:offset}- substring starting at offset${VAR:offset:length}- substring with length${#VAR}- length of VAR${VAR#pattern}- remove shortest match from beginning${VAR##pattern}- remove longest match from beginning${VAR%pattern}- remove shortest match from end${VAR%%pattern}- remove longest match from end${VAR/pattern/replacement}- pattern substitution${VAR//pattern/replacement}- global pattern substitution
- Export mechanism:
export VARandexport VAR=value - Variable scoping: Shell variables vs exported environment variables
- Variable assignment:
- Positional Parameters: Complete support for script arguments and parameter manipulation.
- Individual parameters:
$1,$2,$3, etc. for accessing script arguments - All parameters:
$*and$@for accessing all arguments as a single string - Parameter count:
$#returns the number of positional parameters - Parameter shifting:
shift [n]builtin to shift positional parameters - Script argument passing:
./rush-sh script.sh arg1 arg2 arg3
- Individual parameters:
- Control Structures:
ifstatements:if condition; then commands; elif condition; then commands; else commands; ficasestatements with glob pattern matching:case word in pattern1|pattern2) commands ;; *.txt) commands ;; *) default ;; esac
- Built-in Commands:
cd: Change directoryexit: Exit the shellpwd: Print working directoryenv: List environment variablesexport: Export variables to child processesunset: Remove variablesshift: Shift positional parameterssource/.: 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
- Configuration File: Automatic sourcing of
~/.rushrcon interactive shell startup - Tab Completion: Intelligent completion for commands, files, and directories.
- Command Completion: Built-in commands and executables from PATH
- File/Directory Completion: Files and directories with relative paths
- Directory Traversal: Support for nested paths (
src/,../,/usr/bin/) - Home Directory Expansion: Completion for
~/and~/Documents/paths
- Signal Handling: Graceful handling of SIGINT (Ctrl+C) and SIGTERM.
- Line Editing and History: Enhanced interactive experience with rustyline.
What's New in v0.3.3
🚀 Major Feature Additions
Complete POSIX Parameter Expansion - Full implementation of ${VAR:-default}, ${VAR#pattern}, ${VAR/pattern/replacement}, and all other POSIX parameter expansion modifiers with comprehensive pattern matching and string manipulation capabilities.
Advanced Arithmetic Expansion - Complete $((...)) arithmetic expression evaluator with proper operator precedence, variable integration, bitwise operations, logical operations, and comprehensive error handling using the Shunting-yard algorithm.
Enhanced Built-in Command Suite - Comprehensive set of built-in commands including directory stack management (pushd/popd/dirs), alias management (alias/unalias), color theming (set_colors/set_color_scheme), and POSIX-compliant test builtin.
Intelligent Tab Completion - Advanced completion system for commands, files, directories, and paths with support for nested directory traversal and home directory expansion.
Detailed Feature Updates
Environment Variable Support
Rush 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
$VARsyntax -
Special Variables: Built-in support for special shell variables
-
Export Mechanism: Export variables to child processes
-
Variable Management: Full lifecycle management with
unset -
Multi-Mode Support: Variables work consistently across all execution modes
- Interactive mode: Variables persist across commands
- Script mode: Variables available throughout script execution
- Command string mode: Variables work in
-ccommand strings
Example usage:
# Set and use variables
MY_VAR="Hello from Rush"
# Export to child processes
|
# Use in pipelines
|
# Special variables
if ; then ; fi
Case Statements with Glob Pattern Matching
Rush now supports advanced case statements with full glob pattern matching capabilities:
- Glob Patterns: Use wildcards like
*(any characters),?(single character), and[abc](character classes) - Multiple Patterns: Combine patterns with
|(e.g.,*.txt|*.md) - POSIX Compliance: Full support for standard case statement syntax
- Performance: Efficient pattern matching using the
globcrate
Example usage:
Directory Stack Support (pushd/popd/dirs)
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 stack
Example usage:
# Start in home directory
# /home/user
# Push to /tmp and see stack
# /tmp /home/user
# Push to another directory
# /var /tmp /home/user
# See current stack
# /var /tmp /home/user
# Pop back to /tmp
# /tmp /home/user
# Pop back to home
# /home/user
This feature is particularly useful for:
- Quickly switching between multiple working directories
- Maintaining context when working on different parts of a project
- Scripting scenarios that require directory navigation
Command Substitution
Rush now supports comprehensive command substitution with both $(...) and `...` syntax:
- Dual Syntax Support: Both
$(command)and`command`work identically - Immediate Execution: Commands are executed during lexing and output is substituted inline
- Variable Expansion: Variables within substituted commands are properly expanded
- Error Handling: Failed commands fall back to literal syntax preservation
- Environment Integration: Child processes inherit shell environment variables
- Multi-line Support: Handles commands with multiple lines and special characters
Example usage:
Condensed Current Working Directory in Prompt
Rush now displays a condensed version of the current working directory in the interactive prompt:
- Condensed Path: Each directory except the last is abbreviated to its first letter (preserving case)
- Full Last Directory: The final directory in the path is shown in full
- Dynamic Updates: The prompt updates automatically when changing directories
Example prompt displays:
This feature provides context about your current location while keeping the prompt concise.
Arithmetic Expansion
Rush now supports comprehensive arithmetic expansion using the POSIX-standard $((...)) syntax, enabling mathematical computations directly in shell commands and scripts:
- Basic Arithmetic: Addition, subtraction, multiplication, division, and modulo operations
- Operator Precedence: Standard mathematical precedence with parentheses support
- Variable Integration: Use shell variables directly in arithmetic expressions
- Comparison Operations: Less than, greater than, equal, not equal comparisons (return 1 for true, 0 for false)
- Bitwise Operations: AND, OR, XOR, shift operations for bit-level computations
- Logical Operations: AND, OR, NOT for boolean logic (return 1 for true, 0 for false)
- Error Handling: Division by zero and undefined variable detection
Basic Syntax:
# Simple arithmetic
Variable Usage:
# Variables in arithmetic expressions
x=10
y=3
Operator Precedence:
# Standard precedence: * / % before + -
# Use parentheses to override precedence
# Complex expressions
Comparison Operations:
# Comparisons return 1 (true) or 0 (false)
if [; then ; fi
if [; then ; fi
if [; then ; fi
# Available comparison operators:
# == != < <= > >=
Bitwise and Logical Operations:
# Bitwise operations
# Logical operations (non-zero = true)
Real-world Examples:
# Calculate area of rectangle
length=10
width=5
area=
# Temperature conversion
celsius=25
fahrenheit=
# Array length calculation (simulated)
items=8
per_page=3
pages=
# Conditional logic with arithmetic
count=15
if [; then
else
fi
Error Handling:
# Division by zero produces an error
# Undefined variables cause errors
Advanced Usage:
# Complex mathematical expressions
radius=5
pi=3
area=
# Multiple operations in one expression
result=
# Use in variable assignments
x=10
y= # y = 15
z= # z = 30
Arithmetic expansion integrates seamlessly with all other shell features and works in interactive mode, scripts, and command strings.
# Basic command substitution
# Variable assignments with substitutions
PROJECT_DIR="/src"
FILE_COUNT=""
# Complex expressions
# Error handling
NONEXISTENT=""
# Multiple commands
Command substitution works seamlessly with:
- Pipes and Redirections:
$(echo hello | grep ll) > output.txt - Variable Expansion:
echo $(echo $HOME) - Quoted Strings:
echo "Path: $(pwd)" - Complex Commands:
$(find . -name "*.rs" -exec wc -l {} \;)
Built-in Alias Support
Rush now provides comprehensive built-in alias support, allowing you to create shortcuts for frequently used commands:
- Create Aliases: Define shortcuts with
alias name=valuesyntax - List Aliases: View all defined aliases with
aliascommand - Show Specific Alias: Display a single alias with
alias name - Remove Aliases: Delete aliases with
unalias name - Automatic Expansion: Aliases are expanded automatically during command execution
- Recursion Prevention: Built-in protection against infinite alias loops
Example usage:
# Create aliases
# List all aliases
# Output:
# alias ll='ls -l'
# alias la='ls -la'
# alias ..='cd ..'
# alias grep='grep --color=auto'
# Show specific alias
# Output: alias ll='ls -l'
# Use aliases (they expand automatically)
# Remove aliases
# Error handling
Key Features:
- POSIX Compliance: Follows standard alias syntax and behavior
- Session Persistence: Aliases persist throughout the shell session
- Complex Commands: Support for multi-word commands and pipelines
- Variable Expansion: Variables in aliases are expanded when defined
- Safety: Automatic detection and prevention of recursive aliases
Advanced Usage:
# Complex aliases with pipes and redirections
# Aliases with variables (expanded at definition time)
MY_DIR="/tmp"
# Function-like aliases
# Note: $1 won't work as expected
Implementation Details:
- Aliases are expanded after lexing but before parsing
- Only the first word of a command can be an alias
- Expansion is recursive (aliases can reference other aliases)
- Built-in protection against infinite recursion
- Aliases work in all execution modes (interactive, script, command)
Arithmetic Implementation:
- Uses the Shunting-yard algorithm for proper operator precedence and associativity
- Token-based parsing converts infix expressions to Reverse Polish Notation (RPN)
- Integrated with shell state for seamless variable access during evaluation
- Comprehensive error handling with graceful fallback to literal syntax on errors
Test Builtin with Conditional Logic
Rush now provides comprehensive support for the POSIX test builtin command and its [ bracket syntax, enabling powerful conditional logic in shell scripts:
- String Tests: Check if strings are empty (
-z) or non-empty (-n) - File Tests: Test file existence (
-e), regular files (-f), and directories (-d) - Dual Syntax Support: Both
testand[syntax work identically - POSIX Compliance: Full compatibility with standard test command behavior
- Error Handling: Proper exit codes (0=true, 1=false, 2=error)
- Integration: Seamless integration with shell control structures
Example usage:
# String tests
if ; then ; fi
if [; then ; fi
# File tests
if ; then ; fi
if [; then ; fi
if ; then ; fi
# Complex conditions
if [ && ; then
fi
# Error handling
exit_code=
if [; then ; fi
Key Features:
- String Operations:
-z(zero length) and-n(non-zero length) tests - File Operations:
-e(exists),-f(regular file),-d(directory) - Bracket Syntax:
[ condition ]works identically totest condition - Exit Codes: 0 (true), 1 (false), 2 (error/invalid usage)
- Variable Expansion: Variables are properly expanded in test conditions
- Nested Conditions: Works with complex if/elif/else structures
Advanced Usage:
# Variable existence checks
MY_VAR="hello world"
if ; then
fi
# Safe file operations
TARGET_FILE="/tmp/safe_file.txt"
if ; then
fi
# Directory creation with checks
TARGET_DIR="/tmp/test_dir"
if ; then
else
fi
The test builtin is fully integrated with Rush's control structures, enabling complex conditional logic in scripts while maintaining POSIX compatibility.
Positional Parameters
Rush now provides comprehensive support for positional parameters, enabling scripts to access and manipulate command-line arguments with full POSIX compliance:
- Individual Parameters: Access script arguments using
$1,$2,$3, etc. - All Parameters:
$*and$@provide access to all arguments as a single string - Parameter Count:
$#returns the number of positional parameters as a string - Parameter Shifting:
shift [n]builtin command to manipulate parameter positions - Script Integration: Automatic argument passing when running scripts with
./rush-sh script.sh arg1 arg2
Basic Usage:
# Create a script that uses positional parameters
# Make it executable and run with arguments
# Output: Hello World!
# You provided 1 arguments
# All arguments: World
Advanced Usage:
# Script with multiple arguments
# Output: Script name: process.sh
# First arg: file1.txt
# Second arg: file2.txt
# Total args: 2
# Shifting...
# New first arg: file2.txt
# New arg count: 1
This will demonstrate:
- Individual parameter access (
$1,$2,$3,$4) - Parameter counting (
$#) - All parameters display (
$*,$@) - Parameter shifting with
shiftcommand - Custom shift counts with
shift 2
The script provides comprehensive output showing how each feature works with the provided arguments.
Parameter Manipulation:
# Using shift with custom count
# Output: Original args: a b c d e
# Count: 5
# After shift 2: c d e
# New count: 3
Key Features:
- POSIX Compliance: Follows standard shell parameter expansion behavior
- Variable Integration: Works seamlessly with all other shell features
- Error Handling: Graceful handling of out-of-bounds parameter access
- Multi-Mode Support: Available in interactive mode, scripts, and command strings
- Performance: Efficient parameter storage and access
Integration with Other Features:
# Positional parameters with control structures
# Output: Directory: /tmp
# File: /etc/passwd
# Other: nonexistent
Implementation Details:
- Parameters are stored efficiently in the shell state
- Variable expansion handles parameter access during lexing and execution
- Shift operations modify the parameter array in place
- All parameter operations maintain O(1) access time for individual parameters
Parameter Expansion with Modifiers
Rush now supports comprehensive POSIX sh parameter expansion with modifiers, providing powerful string manipulation capabilities directly in shell commands and scripts:
- Basic Expansion:
${VAR}- Simple variable expansion (equivalent to$VAR) - Default Values:
${VAR:-default}- Use default if VAR is unset or null - Assign Default:
${VAR:=default}- Assign default if VAR is unset or null - Alternative Values:
${VAR:+replacement}- Use replacement if VAR is set and not null - Error Handling:
${VAR:?error}- Display error if VAR is unset or null - Substring Operations:
${VAR:offset}- Extract substring starting at offset${VAR:offset:length}- Extract substring with specified length
- Length Operations:
${#VAR}- Get length of variable content - Pattern Removal:
${VAR#pattern}- Remove shortest match from beginning${VAR##pattern}- Remove longest match from beginning${VAR%pattern}- Remove shortest match from end${VAR%%pattern}- Remove longest match from end
- Pattern Substitution:
${VAR/pattern/replacement}- Replace first occurrence${VAR//pattern/replacement}- Replace all occurrences
- Indirect Expansion:
${!prefix*}- Names of variables starting with prefix
Basic Usage:
# Set a variable
MY_PATH="/usr/local/bin:/usr/bin:/bin"
# Default values
# Assign default if unset
# Alternative values
# Error handling
Substring Operations:
# Extract parts of strings
FILENAME="document.txt"
# Length operations
# Pattern-based length
LONG_STRING="hello world"
Pattern Removal:
# Remove file extensions
FILENAME="document.txt"
# Remove directory paths
FULL_PATH="/usr/bin/ls"
# Remove prefixes
PREFIXED="prefix_value"
Pattern Substitution:
# Replace substrings
GREETING="hello world"
# Multiple replacements
PATH_LIST="/usr/bin:/bin:/usr/local/bin"
Advanced Usage:
# Complex string manipulation
URL="https://example.com/path/to/resource"
|
# Safe variable handling
CONFIG_FILE="/etc/app.conf"
# Dynamic variable names (indirect expansion)
VAR_PREFIX="MY"
VAR_NAME="_VAR"
Integration with Other Features:
# Parameter expansion in control structures
FILENAME="test.txt"
if [; then
fi
# In arithmetic expressions
COUNT=42
# With command substitution
DIR_COUNT=
# In case statements
Key Features:
- POSIX Compliance: Full compatibility with standard parameter expansion syntax
- Performance: Efficient string operations with minimal overhead
- Safety: Robust error handling for edge cases and invalid operations
- Integration: Works seamlessly with all other shell features
- Multi-Mode Support: Available in interactive mode, scripts, and command strings
- Error Resilience: Graceful fallback for malformed expressions
Implementation Details:
- Parameter expansion is handled during the lexing phase for optimal performance
- Pattern matching uses simple string operations for reliability
- All operations maintain compatibility with existing variable expansion
- Comprehensive error handling prevents shell crashes from malformed expressions
- Memory efficient implementation suitable for large variable values
Color Support
Rush now provides comprehensive color support for enhanced terminal output with automatic detection and flexible configuration:
- Automatic Terminal Detection: Colors are enabled in interactive terminals and disabled for pipes/files
- Environment Variable Control: Support for
NO_COLOR=1(accessibility standard) andRUSH_COLORS(explicit control) - Multiple Color Schemes: Default, dark, and light themes with customizable ANSI color codes
- Colored Built-in Commands: Enhanced output for
help,pwd,envwith contextual coloring - Error Highlighting: Red coloring for error messages throughout the shell
- Success Indicators: Green coloring for successful operations
- Runtime Configuration: Dynamic color control with
set_colorsandset_color_schemebuiltins
Example usage:
# Enable colors explicitly
# Disable colors for accessibility
# Switch color schemes
# Control colors dynamically
Key Features:
- Smart Detection: Automatically detects terminal capabilities and disables colors for non-interactive output
- Accessibility: Respects
NO_COLOR=1environment variable for users who prefer monochrome output - Flexible Control:
RUSH_COLORSvariable supportsauto,on,off,1,0,true,falsevalues - Multiple Themes: Three built-in color schemes optimized for different terminal backgrounds
- Contextual Coloring: Different colors for prompts, errors, success messages, and builtin output
- Performance: Minimal overhead when colors are disabled
Color Schemes:
- Default: Standard ANSI colors (green prompt, red errors, cyan builtins, blue directories)
- Dark: Bright colors optimized for dark terminal backgrounds
- Light: Darker colors optimized for light terminal backgrounds
Configuration Options:
# Environment variables
# Disable colors (accessibility)
# Auto-detect (default)
# Force enable
# Force disable
# Runtime commands
The color system is designed to be both powerful and unobtrusive, providing visual enhancements while respecting user preferences and accessibility needs.
.rushrc Configuration File
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:
- Environment Variables: Set default variables and export them to child processes
- Aliases: Define command shortcuts that persist across the session
- Shell Configuration: Customize prompt, PATH, or other shell settings
- Initialization Commands: Run setup commands on shell startup
Example ~/.rushrc file:
# Set environment variables
# Create useful aliases
# Set custom variables
MY_PROJECTS="/projects"
WORKSPACE="/workspace"
# Display welcome message
Key Features:
- Automatic Loading: Sourced automatically when entering interactive mode
- Silent Failures: Missing or invalid
.rushrcfiles don't prevent shell startup - Variable Persistence: Variables and aliases set in
.rushrcare available throughout the session - Error Resilience: Syntax errors in
.rushrcare handled gracefully - Standard Location: Uses
~/.rushrcfollowing Unix conventions
Usage Notes:
- Only loaded in interactive mode (not in script or command-line modes)
- Variables set in
.rushrcare available to all subsequent commands - Use
exportto make variables available to child processes - Comments (lines starting with
#) are ignored - Multi-line constructs (if/fi, case/esac) are supported
Installation
Prerequisites
- Rust (edition 2024 or later)
Cargo Installation
-
Install rush-sh from crates.io:
Build
-
Clone the repository:
-
Build the project:
The binary will be available at target/release/rush-sh.
Usage
Interactive Mode
Run the shell without arguments to enter interactive mode:
or
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.
Script Mode
Execute commands from a file:
or
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.
Command Mode
Execute a command string directly:
or
The shell will execute the provided command string and exit.
Source Command
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:
This is particularly useful for:
- Executing scripts written for rush that contain
#!/usr/bin/env rush-shshebangs - Running scripts with shebangs for other shells (like
#!/usr/bin/env bash) using rush instead - Ensuring consistent execution environment regardless of shebang declarations
- Sharing variables between the sourced script and the parent shell
Unlike 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.
Examples
- Run a command:
ls -la - Use pipes:
ls | grep txt - Redirect output:
echo "Hello" > hello.txt - Change directory:
cd /tmp - Print working directory:
pwd - Directory stack management:
- Push directory:
pushd /tmp - Pop directory:
popd - Show stack:
dirs
- Push directory:
- Execute a script:
source script.sh - Execute a script with dot:
. script.sh - Execute a script with shebang bypass:
source examples/basic_commands.sh - Execute elif example script:
source examples/elif_example.sh - Execute case example script:
source examples/case_example.sh - Execute variables example script:
source examples/variables_example.sh - Execute complex example script with command substitution:
source examples/complex_example.sh - Execute positional parameters demo:
source examples/positional_parameters_demo.sh - Alias management:
- Create aliases:
alias ll='ls -l'; alias la='ls -la' - List aliases:
alias - Show specific alias:
alias ll - Remove aliases:
unalias ll - Use aliases:
ll /tmp
- Create aliases:
- Environment variables:
- Set variables:
MY_VAR=hello; echo $MY_VAR - Export variables:
export MY_VAR=value; env | grep MY_VAR - Special variables:
echo "Exit code: $?"; echo "PID: $$" - Quoted values:
NAME="John Doe"; echo "Hello $NAME"
- Set variables:
- Positional parameters:
- Access arguments:
echo "First arg: $1, Second: $2" - Argument count:
echo "You provided $# arguments" - All arguments:
echo "All args: $*" - Shift parameters:
shift; echo "New first: $1" - Custom shift:
shift 2; echo "After shift 2: $*"
- Access arguments:
- Use control structures:
- If statement:
if true; then echo yes; else echo no; fi - If-elif-else statement:
if false; then echo no; elif true; then echo yes; else echo maybe; fi - Case statement with glob patterns:
- Simple match:
case hello in hello) echo match ;; *) echo no match ;; esac - Glob patterns:
case file.txt in *.txt) echo "Text file" ;; *.jpg) echo "Image" ;; *) echo "Other" ;; esac - Multiple patterns:
case file in *.txt|*.md) echo "Document" ;; *.exe|*.bin) echo "Executable" ;; *) echo "Other" ;; esac - Character classes:
case letter in [abc]) echo "A, B, or C" ;; *) echo "Other letter" ;; esac
- Simple match:
- If statement:
- Test builtin for conditional logic:
- String tests:
if test -z "$VAR"; then echo "Variable is empty"; fi - File tests:
if [ -f "/etc/passwd" ]; then echo "File exists"; fi - Combined conditions:
if test -n "$NAME" && [ -d "/tmp" ]; then echo "Ready"; fi - Error handling:
test -x "invalid"; echo "Exit code: $?"
- String tests:
- Command substitution:
- Basic substitution:
echo "Current dir: $(pwd)" - Backtick syntax:
echo "Files:ls | wc -l" - Variable assignments:
PROJECT_DIR="$(pwd)/src" - Complex commands:
echo "Rust version: $(rustc --version | cut -d' ' -f2)" - Error handling:
RESULT="$(nonexistent_command 2>/dev/null || echo 'failed')" - With pipes:
$(echo hello | grep ll) > output.txt - Multiple commands:
echo "Output: $(echo 'First'; echo 'Second')"
- Basic substitution:
- Arithmetic expansion:
- Basic arithmetic:
echo "Result: $((2 + 3 * 4))" - Variable calculations:
result=$((x * y + z)) - Comparisons:
if [ $((count % 2)) -eq 0 ]; then echo "Even"; fi - Complex expressions:
area=$((length * width)) - Temperature conversion:
fahrenheit=$((celsius * 9 / 5 + 32))
- Basic arithmetic:
- Parameter expansion with modifiers:
- Default values:
echo "Home: ${HOME:-/home/user}" - Substring extraction:
echo "Extension: ${FILENAME:9}" - Pattern removal:
echo "Basename: ${FULL_PATH##*/}" - Pattern substitution:
echo "Replaced: ${TEXT/old/new}" - Length operations:
echo "Length: ${#VARIABLE}"
- Default values:
- Tab completion:
- Complete commands:
cd→cd,env,exit - Complete files:
cat f→cat file.txt - Complete directories:
cd src/→cd src/main/ - Complete from PATH:
l→ls,g→grep - Complete nested paths:
ls src/m→ls src/main/
- Complete commands:
Architecture
Rush consists of the following components:
- Lexer: Tokenizes input into commands, operators, and variables with support for variable expansion, parameter expansion with modifiers (
${VAR:-default},${VAR#pattern}, etc.), command substitution ($(...)and`...`syntax), arithmetic expansion ($((...))), and alias expansion. - Parser: Builds an Abstract Syntax Tree (AST) from tokens, including support for complex control structures, case statements with glob patterns, and variable assignments.
- Executor: Executes the AST, handling pipes, redirections, built-ins, glob pattern matching, environment variable inheritance, command substitution execution, and arithmetic expression evaluation.
- Arithmetic Engine: A comprehensive arithmetic expression evaluator implemented in
src/arithmetic.rsthat supports:- Token-based parsing: Converts expressions to tokens and uses the Shunting-yard algorithm for proper operator precedence
- Variable integration: Seamlessly accesses shell variables during evaluation
- Comprehensive operators: Arithmetic, comparison, bitwise, and logical operations with correct precedence
- Error handling: Robust error reporting for syntax errors, division by zero, and undefined variables
- Unary operators: Support for both logical NOT (
!) and bitwise NOT (~) operations
- Parameter Expansion Engine: A comprehensive parameter expansion system implemented in
src/parameter_expansion.rsthat supports:- Modifier parsing: Sophisticated parsing of POSIX sh parameter expansion modifiers
- String operations: Default values, substring extraction, pattern removal, and substitution
- Error handling: Robust error reporting for malformed expressions and edge cases
- Performance: Efficient string manipulation with minimal memory allocation
- Shell State: Comprehensive state management for environment variables, exported variables, special variables (
$?,$$,$0), current directory, directory stack, and command aliases. - Built-in Commands: Optimized detection and execution of built-in commands including variable management (
export,unset,env) and alias management (alias,unalias). - Completion: Provides intelligent tab-completion for commands, files, and directories.
Dependencies
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.regex: For advanced pattern matching in parameter expansion.
Quality Assurance
Comprehensive Test Suite
Rush includes an extensive test suite with 100+ test cases ensuring reliability and correctness:
- Unit Tests: Individual component testing for lexer, parser, arithmetic engine, and parameter expansion
- Integration Tests: End-to-end command execution, pipelines, redirections, and control structures
- Built-in Command Tests: Comprehensive coverage of all built-in command functionality
- Error Handling Tests: Robust testing of edge cases, syntax errors, and failure scenarios
- Feature-Specific Tests: Dedicated test suites for arithmetic expansion, parameter expansion, and POSIX compliance
Test Coverage Areas:
- Command parsing and execution
- Variable expansion and parameter modifiers
- Arithmetic expression evaluation
- Control structures (if/elif/else, case statements)
- Built-in command functionality
- Pipeline and redirection handling
- Tab completion system
- Error conditions and edge cases
Testing
Run the complete test suite with:
Test Structure
- Lexer Tests Tokenization of commands, arguments, operators, quotes, variable expansion, command substitution, arithmetic expansion, and edge cases.
- Parser Tests AST construction for single commands, pipelines, redirections, if-elif-else statements, case statements with glob patterns, and error cases.
- Executor Tests Built-in commands, external command execution, pipelines, redirections, case statement execution with glob matching, command substitution execution, and error handling.
- Completion Tests Tab-completion for commands, files, directories, path traversal, and edge cases.
- Integration Tests End-to-end command execution, including pipelines, redirections, variable expansion, case statements, and command substitution.
- Main Tests Error handling for invalid directory changes.
Running Tests
Run all tests with:
Run specific test modules:
Test Coverage
The test suite provides extensive coverage of:
- Command parsing and execution
- Built-in command functionality (cd, pwd, env, exit, help, source, export, unset, shift, pushd, popd, dirs, alias, unalias, test, [)
- Pipeline and redirection handling
- Control structures (if-elif-else statements, case statements with glob patterns)
- Command substitution (
$(...)and`...`syntax, error handling, variable expansion) - Arithmetic expansion (
$((...))syntax, operator precedence, variable integration, error handling) - Positional parameters (
$1,$2,$*,$@,$#,shiftcommand) - Parameter expansion with modifiers (
${VAR:-default},${VAR#pattern},${VAR/pattern/replacement}, etc.) - Environment variable support (assignment, expansion, export, special variables)
- Variable scoping and inheritance
- Tab-completion for commands, files, and directories
- Path traversal and directory completion
- Error conditions and edge cases
- Signal handling integration
Contributing
Contributions are welcome! Please fork the repository, make your changes, and submit a pull request.
License
This project is licensed under the MIT License. See LICENSE.txt for details.