A lightweight, standalone Unix shell implementation written in Rust for embedded Linux environments. This shell handles basic navigation, file manipulation, and essential shell behaviors without relying on existing shell utilities.
- Overview
- Learning Objectives
- Features
- Built-in Commands
- Project Structure
- Installation
- Usage
- Technical Implementation
- Bonus Features
- Example Session
This project implements a minimalist Unix shell that:
- Displays a prompt (
$) and waits for user input - Parses and executes user commands
- Returns to the prompt only after command execution completes
- Handles
Ctrl+D(EOF) gracefully to exit the shell - Prints
Command '<name>' not foundfor unrecognized commands
- Work with file and directory operations
- Manage user input and output within a shell loop
- Implement robust error handling
- Gain experience in Unix process and system call APIs
- Command Parsing: Supports single and double quoting, escape sequences
- Environment Variables: Expansion of
$VARand${VAR}syntax - Home Directory Expansion:
~expands to$HOME - Quote Continuation: Multi-line input for unclosed quotes with
dequote>prompt - ANSI Escape Handling: Cleans cursor movement sequences from input
- No external binaries or system calls that spawn them
- Basic command syntax only (no piping
|, redirection>, or globbing*) - Shell behavior aligns with Unix conventions
| Command | Description | Flags |
|---|---|---|
echo |
Print arguments to stdout with escape sequence support | Supports \n, \t, \r, \\, \", \', \xNN |
cd |
Change current working directory | - (none, goes to $HOME) |
ls |
List directory contents | -l (long format), -a (show hidden), -F (classify) |
pwd |
Print current working directory | - |
cat |
Concatenate and print files | Reads from stdin if no args |
cp |
Copy files | - |
rm |
Remove files or directories | -r (recursive) |
mv |
Move or rename files/directories | - |
mkdir |
Create directories | - |
clear |
Clear terminal screen | - |
exit |
Exit the shell | - |
0-shell/
βββ Cargo.toml # Rust package manifest
βββ README.md # This file
βββ src/
βββ main.rs # Main shell loop and command dispatcher
βββ parse.rs # Input parsing, tokenization, variable expansion
βββ commands/
βββ mod.rs # Module declarations
βββ cat.rs # cat command implementation
βββ cd.rs # cd command implementation
βββ clear.rs # clear command implementation
βββ cp.rs # cp command implementation
βββ echo.rs # echo command implementation
βββ ls.rs # ls command implementation (with -l, -a, -F)
βββ mkdir.rs # mkdir command implementation
βββ mv.rs # mv command implementation
βββ pwd.rs # pwd command implementation
βββ rm.rs # rm command implementation (with -r)
- Rust toolchain (rustc, cargo) - Install from rustup.rs
# Clone the repository
git clone https://github.com/AyyoubMh48/0-shell.git
cd 0-shell
# Build the project
cargo build --release
# The binary will be at target/release/kinda_shell# Run the shell
cargo run
# Or run the compiled binary directly
./target/release/kinda_shell| Crate | Version | Purpose |
|---|---|---|
chrono |
0.4.41 | Date/time formatting for ls -l |
chrono-tz |
0.10.4 | Timezone support |
iana-time-zone |
0.1.63 | System timezone detection |
regex |
1.11.1 | Input cleaning (ANSI escape removal) |
terminal_size |
0.4.2 | Terminal width for column formatting |
users |
0.11.0 | User/group name resolution |
xattr |
1.0.1 | Extended attributes support |
Cmdstruct: Holds parsed command name and argumentsclean_input(): Removes ANSI cursor movement sequencessplit(): Tokenizes input with:- Single/double quote handling
- Environment variable expansion (
$VAR,${VAR}) - Home directory expansion (
~) - Unclosed quote detection (returns error for continuation)
- Displays
$prompt - Reads user input line by line
- Handles EOF (
Ctrl+D) for graceful exit - Supports quote continuation with
dequote>prompt - Dispatches commands to appropriate handlers
Each command is implemented as a separate module with its own function:
echo: Full escape sequence support including hex (\xNN)cd: Changes directory, defaults to$HOMEif no argumentls: Full-lformat with permissions, links, owner, group, size, time, and file classification (-F)pwd: Prints current working directorycat: Reads files or stdincp: Copies files (no recursive directory copy)rm: Removes files,-rfor recursive directory removalmv: Moves/renames files and directoriesmkdir: Creates directoriesclear: Clears terminal using ANSI escape codes
- β
Environment variable support (
$HOME,$PATH, etc.) - β Quote continuation for multi-line input
- β
Extended
lsoutput with file classification (-F) - β Clear command for terminal management
- β¬ Handle
Ctrl+C(SIGINT) without crashing - β¬ Auto-completion
- β¬ Command history
- β¬ Prompt with current directory (e.g.,
~/projects/0-shell $) - β¬ Colorized output
- β¬ Command chaining with
; - β¬ Pipes (
|) - β¬ I/O redirection (
>,<) - β¬ Custom
helpcommand
student$ ./target/release/kinda_shell
$ cd dev
$ pwd
/dev
$ ls -l
total 0
crw------- 1 root root 10, 58 Feb 5 09:21 acpi_thermal_rel
crw-r--r-- 1 root root 10, 235 Feb 5 09:21 autofs
drwxr-xr-x 2 root root 540 Feb 5 09:21 block
...
$ something
Command 'something' not found
$ echo "Hello There"
Hello There
$ echo $HOME
/home/student
$ mkdir test_dir
$ ls
test_dir
$ rm -r test_dir
$ exit
student$This project is evaluated based on:
| Criteria | Description |
|---|---|
| Functionality | Commands perform correctly and emulate standard Unix behavior |
| Stability | Shell handles user errors, invalid input, and edge cases without crashing |
| Code Quality | Clean, well-documented, and maintainable code |
| Error Handling | Appropriate error messages for invalid operations |
This project is part of an educational assignment.
- AyyoubMh48 - GitHub