Flash is a Unix-style shell written in Rust to explore how real shells work under the hood. The project focuses on process creation, pipes, redirection, job control, and parsing command syntax into an executable AST.
It is intentionally built with low-level system calls (fork, execvp, waitpid, pipe, dup2, sigaction, setpgid, tcsetpgrp) so the execution model stays explicit and close to the OS.
- External command execution via
fork+execvp - Pipelines:
cmd1 | cmd2 - Redirection:
<,>,>> - Logical operators:
&&,|| - Command sequencing:
; - Background execution:
& - Built-ins:
cd,jobs,exit - Quoted string literals and escaped characters in the lexer
Flash is split into clear stages:
Lexer (
src/lexer/mod.rs)- Converts raw input into shell tokens.
- Handles operators (
|,&&,||, redirects,;,&), words, and string literals.
Parser (
src/parser/mod.rs)- Uses recursive descent to build an AST.
- Produces nodes for simple commands, pipes, redirects, conditionals, sequences, and background jobs.
Executor (
src/executor/mod.rs)- Walks the AST and executes nodes recursively.
- Manages file descriptors and anonymous pipes for stream routing.
- Handles foreground/background process behavior and child reaping.
Runtime and Built-ins (
src/main.rs,src/utils/mod.rs)- Runs the shell loop.
- Tracks execution context (job table, shell PGID, exit status).
- Installs/ignores terminal-related signals in the shell process.
- Rust toolchain (stable)
- Linux or Unix-like environment
cargo build
cargo runYou will get an interactive prompt:
$
# basic execution
ls -la
# pipelines
cat Cargo.toml | grep edition
# redirectionecho hello > out.txt
cat < out.txt
echo world >> out.txt
# conditionals
mkdir test&&cdtest
cat missing_file ||echo"fallback"# sequencingpwd; ls
# background jobs
sleep 10 &jobs- This project is educational and under active iteration; behavior may differ from
bash/zshin edge cases. - No glob expansion (
*), environment variable expansion ($VAR), command substitution, or scripting support yet. - Parsing/execution precedence is implemented for supported operators, but shell grammar coverage is intentionally minimal.
Flash was built to gain hands-on systems experience in:
- Linux process and signal semantics
- IPC and file descriptor lifecycle management
- Recursive command execution over ASTs
- Building language frontends (tokenizer + parser) for a real runtime
- Improve POSIX behavior compatibility
- Add variable expansion and quoting edge-case handling
- Add tests for lexer/parser/executor invariants
- Improve job control and terminal state transitions