A minimalist Unix-like shell implemented in Rust for embedded Linux environments.
0-shell is a lightweight, standalone shell written in Rust that implements a set of builtin Unix-like commands without spawning external shells (bash/sh). The project focuses on minimalism and portability for constrained or embedded Linux targets while demonstrating core shell concepts: command parsing, filesystem operations, and user interaction.
Repository: https://github.com/astaaa48/0-Shell
- Interactive prompt and command loop
- Built-in implementations for core commands (no external binaries required by the shell itself)
- Graceful handling of EOF (Ctrl+D) and common errors
- Colorized help output
- Small codebase suitable for learning and extension
Implemented builtins (core):
echo, cd, pwd, ls, cat, cp, rm, mv, mkdir, exit, help
Note: The project also includes small external helper binaries under
external/that can be built and copied intoexternal/binfor convenience.
- Rust toolchain (
cargo+rustc) - GNU Make (for the provided Makefile)
- Linux (development and run tested on Linux)
The repository includes a Makefile that automates building the main shell and optional external helper commands.
- Build everything (clean → build main shell → build listed external commands → copy binaries into
external/bin):
make build
* **Build + run the shell** with the local `external/bin` prepended in PATH:
```bash
make run- Run an already-built binary using the Makefile PATH configuration:
make bin- Clean build artifacts and copied binaries:
make cleanMakefile highlights (can be passed as environment variables):
SHELL_NAME— name of the main binary (default:zero_shell)COMMANDS— external commands to build and copy intoexternal/binBIN_DIR— destination directory for copied binaries (default:external/bin)TARGET_DIR— cargo target directory (default:$(CURDIR)/target)QUIET=true— run cargo build quietlyEXTERNAL=true— when set,make runwill include the existing PATH in addition toexternal/bin
Examples:
- Quiet build:
QUIET=true make build- Run shell but preserve system PATH so external commands (e.g., system tools) remain available:
EXTERNAL=true make run- Runs
cargo buildfor the main package - Iterates the
COMMANDSlist (e.g.,cat clear cp ls mkdir mv rm) and runscargo build -p <cmd>to build each external helper crate inexternal/ - Copies built artifacts from
target/debug/intoexternal/bin/ - The
runtarget sets PATH to includeexternal/bin(or that plus existing PATH whenEXTERNAL=true) before launching the shell
This workflow allows the shell to execute helper commands placed under
external/binduring interactive sessions.
After building:
- Launch the shell with the local PATH override used by the Makefile:
export PATH="$(pwd)/external/bin:$(PATH)"
external/bin/zero_shell- Or, directly run the built binary:
target/debug/zero_shellAt the shell prompt ($):
- Change directory:
$ cd /tmp- Print working directory:
$ pwd- Print a line:
$ echo "Hello World"- Get help:
$ help
$ help echo- Exit:
$ exit
# (or press Ctrl+D)- Each builtin command exposes a
pub fn run(args: Vec<String>) -> i32that returns a POSIX-like exit status (0success, non-zero failure codes). Look atsrc/commands/*for examples (cd.rs,echo.rs,pwd.rs,help.rs) helpuses thecoloredcrate to render a framed help menuechosupports prompting to complete unclosed quotes usingrustylinefor continuation input and returns non-zero on interrupt or EOFcdupdatesOLDPWDand reports error exit codes for failure cases
src/ — main shell implementation and builtin command modules
└─ commands/ — builtin command implementations (cd, echo, pwd, help, exit, ...)
└─ shell.rs
└─ parser.rs
└─ main.rs — main loop and parsing
external/ — optional small helper crates and final `external/bin` target
Makefile — build/run automation
-
Cargo build failures:
- Ensure Rust toolchain is installed (rustup/cargo)
- Check crate features and
Cargo.tomlinexternal/*crates
-
Missing binaries in
external/binaftermake build:- Confirm
target/debug/<cmd>exists - Ensure
COMMANDSvariable lists the external crates you expect built
- Confirm
-
PATH issues when running:
- Use
EXTERNAL=true make runto preserve the system PATH if you need system commands available
- Use
-
Permission denied launching copied binaries:
- Ensure
external/bin/*are executable:
- Ensure
chmod +x external/bin/*- Add or improve builtin commands under
src/commands - Add small utility crates under
external/and add their names toCOMMANDSin the Makefile if you want them copied toexternal/binautomatically - Open issues or pull requests with clear descriptions and tests where applicable