Skip to content

Repository files navigation

Flash Shell

A POSIX-compliant shell parser, formatter, and interpreter implemented in Rust.

Flash is a high-performance, extensible toolkit for processing POSIX-style shell scripts. The system comprises three primary components: a lexical analyzer, a syntax parser, and an execution interpreter, all implemented from the ground up in Rust. Flash provides comprehensive support for real-world shell syntax and offers structured Abstract Syntax Tree (AST) access for static analysis, code transformation, and tooling development.

The project draws inspiration from mvdan/sh while prioritizing performance optimization and architectural extensibility through modern systems programming practices.

Development Status: This project is currently under active development and should be considered experimental for production use cases.

Table of Contents

Feature Coverage

The following table provides a comprehensive overview of POSIX Shell and Bash feature support within the Flash implementation. This matrix serves as both a development roadmap and compatibility reference.

Legend:

  • Fully Supported: Complete implementation with full functionality
  • Parser Only: Syntax recognition and AST generation without execution support
  • Not Supported: Feature not currently implemented
CategoryFunctionality / FeaturePOSIX ShellBashFlashImplementation Notes
Basic SyntaxVariable assignmentFully SupportedFully SupportedFully SupportedVAR=value syntax
Command substitutionFully SupportedFully SupportedFully SupportedBoth $(cmd) and `cmd` forms
Arithmetic substitutionNot SupportedFully SupportedFully Supported$((expr)) evaluation
Comments (#)Fully SupportedFully SupportedFully SupportedStandard comment syntax
Quoting (', "", \)Fully SupportedFully SupportedFully SupportedAll quoting mechanisms
Globbing (*, ?, [...])Fully SupportedFully SupportedFully SupportedPattern matching
Control Structuresif / else / elifFully SupportedFully SupportedFully SupportedConditional execution
case / esacFully SupportedFully SupportedFully SupportedPattern matching constructs
for loopsFully SupportedFully SupportedFully SupportedIteration constructs
while, until loopsFully SupportedFully SupportedFully SupportedLoop constructs
select loopNot SupportedFully SupportedFully SupportedInteractive selection
[[ ... ]] test commandNot SupportedFully SupportedFully SupportedExtended test expressions
FunctionsFunction definition (name() {})Fully SupportedFully SupportedFully SupportedStandard function syntax
function keywordNot SupportedFully SupportedFully SupportedBash-specific syntax
I/O RedirectionOutput/input redirection (>, <, >>)Fully SupportedFully SupportedFully SupportedStandard redirection
Here documents (<<, <<-)Fully SupportedFully SupportedParser OnlyPartial implementation
Here strings (<<<)Not SupportedFully SupportedParser OnlyPartial implementation
File descriptor duplication (>&, <&)Fully SupportedFully SupportedParser OnlyPartial implementation
Job ControlBackground execution (&)Fully SupportedFully SupportedFully SupportedProcess backgrounding
Job control commands (fg, bg, jobs)Fully SupportedFully SupportedFully SupportedInteractive mode only
Process substitution (<(...), >(...))Not SupportedFully SupportedParser OnlyBasic <(cmd) support
ArraysIndexed arraysNot SupportedFully SupportedFully Supportedarr=(a b c) syntax
Associative arraysNot SupportedFully SupportedNot Supporteddeclare -A requirement
Parameter Expansion${var} basic expansionFully SupportedFully SupportedFully SupportedVariable expansion framework
${var:-default}, ${var:=default}Fully SupportedFully SupportedFully SupportedDefault value expansion
${#var}, ${var#pattern}Fully SupportedFully SupportedFully SupportedLength and pattern operations
${!var} indirect expansionNot SupportedFully SupportedFully SupportedVariable indirection
${var[@]} / ${var[*]} array expansionNot SupportedFully SupportedNot SupportedArray element expansion
Command ExecutionPipelinesFully SupportedFully SupportedFully SupportedCommand chaining
Logical AND / OR (&&, ``)Fully SupportedFully Supported
Grouping (( ), { })Fully SupportedFully SupportedFully SupportedCommand grouping
Subshell (( ))Fully SupportedFully SupportedFully SupportedIsolated execution context
Coprocesses (coproc)Not SupportedFully SupportedNot SupportedBidirectional pipes
Builtinscd, echo, test, read, eval, etc.Fully SupportedFully SupportedFully SupportedCore built-in commands
shopt, declare, typesetNot SupportedFully SupportedNot SupportedBash-specific builtins
let, local, exportFully SupportedFully SupportedFully SupportedVariable management
Debuggingset -x, set -e, trapFully SupportedFully SupportedParser OnlyPartial debugging support
BASH_SOURCE, FUNCNAME arraysNot SupportedFully SupportedNot SupportedRuntime introspection
MiscellaneousBrace expansion ({1..5})Not SupportedFully SupportedFully SupportedSequence generation
Extended globbing (extglob)Not SupportedFully SupportedNot SupportedRequires shopt configuration
Version variables ($BASH_VERSION)Not SupportedFully SupportedFully Supported$FLASH_VERSION in Flash
Script sourcing (. or source)Fully SupportedFully SupportedFully SupportedExternal script inclusion

Shell Implementation

Theoretical Foundation

A shell fundamentally operates as a macro processor that executes commands, where macro processing refers to the expansion of text and symbols into more complex expressions. The Unix shell paradigm encompasses dual functionality: serving as both a command interpreter and a programming language environment.

As a command interpreter, the shell provides the primary user interface to the comprehensive suite of Unix utilities and system commands. The programming language capabilities enable the composition and combination of these utilities into more sophisticated operations. Shell scripts, containing sequences of commands, achieve the same execution status as system binaries located in standard directories such as /bin, enabling users and organizations to establish customized automation environments.

Shell execution operates in two primary modes: interactive and non-interactive. Interactive mode processes user input from keyboard interfaces in real-time, while non-interactive mode executes command sequences from script files.

Flash maintains substantial compatibility with both POSIX shell (sh) and Bash specifications, implementing the core language features and execution semantics expected by existing shell scripts.

Production Readiness: Flash is currently in active development and should be evaluated carefully before deployment in production environments.

Installation Methods

Method 1: Cargo Package Manager

cargo install flash

Method 2: Source Installation

git clone https://github.com/raphamorim/flash.git
cd flash && cargo install --path .

Method 3: Manual Binary Installation

git clone https://github.com/raphamorim/flash.git
cd flash
cargo build --release
# Linux systems
sudo cp target/release/flash /bin/
# macOS/BSD systems
sudo cp target/release/flash /usr/local/bin/
# Verify installation
flash

System Integration

Default Shell Configuration

To configure Flash as the default system shell:

# Add Flash binary path to system shells registry
vim /etc/shells
# Linux systems
chsh -s /bin/flash
# macOS/BSD systems
chsh -s /usr/local/bin/flash

Configuration Management

Flash implements a configuration system through the .flashrc initialization file located in the user's home directory. This file executes during shell startup, enabling environment customization and initialization script execution.

Prompt Customization

The shell prompt can be customized through the PROMPT environment variable within the .flashrc configuration file:

# Minimal prompt configurationexport PROMPT="flash> "# Directory-aware promptexport PROMPT='flash:$PWD$ '# Full context prompt with user and hostnameexport PROMPT='$USER@$HOSTNAME:$PWD$ '

The PROMPT variable supports full variable expansion, allowing integration of any available environment variables into the prompt display.

Configuration Example

# Prompt configurationexport PROMPT='flash:$PWD$ '# Standard environment variablesexport EDITOR=vim
export PAGER=less
# Future alias support (planned feature)# alias ll="ls -la"# alias grep="grep --color=auto"

Library Integration

Flash provides comprehensive library functionality for integration into Rust applications, supporting multiple use cases including testing frameworks, shell script parsing, custom shell backend development, code formatting, and static analysis tooling.

A WebAssembly version with interactive documentation and examples is available at raphamorim.io/flash.

Interpreter Integration

The Flash interpreter can be embedded directly into Rust applications:

use flash::interpreter::Interpreter;use std::io;fnmain() -> io::Result<()>{letmut interpreter = Interpreter::new();
interpreter.run_interactive()?;Ok(())}

The run_interactive method utilizes Flash's default evaluation engine:

// Default interactive shell implementationpubfnrun_interactive(&mutself) -> io::Result<()>{let default_evaluator = DefaultEvaluator;self.run_interactive_with_evaluator(default_evaluator)}

Custom Evaluation Engine

Flash supports custom evaluation logic through the Evaluator trait, enabling specialized shell behavior:

// Evaluation trait for custom implementationspubtraitEvaluator{fnevaluate(&mutself,node:&Node,interpreter:&mutInterpreter) -> Result<i32, io::Error>;}// Standard shell behavior implementationpubstructDefaultEvaluator;implEvaluatorforDefaultEvaluator{fnevaluate(&mutself,node:&Node,interpreter:&mutInterpreter) -> Result<i32, io::Error>{match node {Node::Command{ name, args, redirects } => {self.evaluate_command(name, args, redirects, interpreter)}Node::Pipeline{ commands } => {self.evaluate_pipeline(commands, interpreter)}Node::List{ statements, operators } => {self.evaluate_list(statements, operators, interpreter)}Node::Assignment{ name, value } => {self.evaluate_assignment(name, value, interpreter)}// Additional node types...
_ => Err(io::Error::other("Unsupported node type")),}}}

The DefaultEvaluator implements comprehensive shell semantics including built-in command handling, pipeline execution, variable assignment, and external command invocation with proper environment variable propagation and I/O redirection support.

Lexical Analysis

Flash provides direct access to its lexical analyzer for token-level processing:

fntest_tokens(input:&str,expected_tokens:Vec<TokenKind>){letmut lexer = Lexer::new(input);for expected in expected_tokens {let token = lexer.next_token();assert_eq!(
token.kind, expected,"Expected {:?} but got {:?} for input: {}",
expected, token.kind, input
);}// Verify complete token consumptionlet final_token = lexer.next_token();assert_eq!(final_token.kind,TokenKind::EOF);}#[test]fntest_function_declaration(){let input = "function greet() { echo hello; }";let expected = vec![TokenKind::Function,TokenKind::Word("greet".to_string()),TokenKind::LParen,TokenKind::RParen,TokenKind::LBrace,TokenKind::Word("echo".to_string()),TokenKind::Word("hello".to_string()),TokenKind::Semicolon,TokenKind::RBrace,];test_tokens(input, expected);}

Syntax Analysis

The parser component transforms token streams into structured Abstract Syntax Trees:

use flash::lexer::Lexer;use flash::parser::Parser;#[test]fntest_simple_command(){let input = "echo hello world";let lexer = Lexer::new(input);letmut parser = Parser::new(lexer);let result = parser.parse_script();match result {Node::List{ statements, operators } => {assert_eq!(statements.len(),1);assert_eq!(operators.len(),0);match&statements[0]{Node::Command{ name, args, redirects } => {assert_eq!(name,"echo");assert_eq!(args,&["hello","world"]);assert_eq!(redirects.len(),0);}
_ => panic!("Expected Command node"),}}
_ => panic!("Expected List node"),}}

Code Formatting

Flash includes a comprehensive formatter for shell script standardization:

// String-based formattingassert_eq!(Formatter::format_str(" # This is a comment"),"# This is a comment");
// AST-based formattingletmut formatter = Formatter::new();let node = Node::Comment(" This is a comment".to_string());assert_eq!(formatter.format(&node),"# This is a comment");

References

License

This project is licensed under the GPL-3.0 License. Copyright © Raphael Amorim.

About

⚡ shell parser, formatter, and interpreter with Bash support

Topics

Resources

Stars

118 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages