Skip to content

🐚 A Unix shell built in C from scratch β€” parsing, processes, pipes and Bash behavior. 42 School.

Notifications You must be signed in to change notification settings

HazeltheJ/minishell

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🐚 Minishell

A faithful Bash-inspired shell, built from scratch in C

C 42 Status Team


πŸ“– About

Minishell is one of the most challenging projects at 42 β€” and one of the most rewarding.

The goal is simple to state: build a shell that behaves like Bash. The reality is far more complex. We had to deeply understand how a real shell works internally β€” how raw text input gets transformed into executable commands, how processes are spawned and connected, and how the terminal itself communicates with the OS.

Parsing was the first major challenge. Turning a raw string like echo "hello $USER" | grep -v root >> out.txt into a structured, executable command tree requires handling quotes, variable expansion, operators, and edge cases that Bash has spent decades refining. We built our own lexer and parser from scratch to handle it correctly.

Process and pipe management was the second. Every command in a pipeline runs in its own child process, connected through file descriptors. Getting fork(), pipe(), dup2() and waitpid() to work together reliably β€” without leaking file descriptors or creating zombie processes β€” required a thorough understanding of Unix process management.

Throughout the project, our reference was always Bash itself. When in doubt, we tested the behavior in Bash and matched it. The result is a shell that handles the vast majority of real-world use cases correctly.


✨ Features

  • Interactive prompt with command history
  • Command execution via PATH resolution
  • Pipes | β€” unlimited chaining of commands
  • Redirections:
    • < input redirection
    • > output redirection
    • >> append to file
    • << heredoc
  • Environment variable expansion β€” $VAR, $?
  • Quote handling β€” single ' and double " quotes
  • Signals β€” Ctrl+C, Ctrl+D, Ctrl+\ mirroring Bash behavior
  • Built-in commands:
Command Description
echo Print text (-n flag supported)
cd Change directory (relative & absolute)
pwd Print current working directory
export Set or update environment variables
unset Remove environment variables
env Display all environment variables
exit Exit the shell with a status code

πŸš€ Getting Started

Requirements

  • GCC
  • Make
  • Unix-based OS (Linux / macOS)
  • readline library
# On Ubuntu/Debian
sudo apt install libreadline-dev

Installation

git clone https://github.com/YourName/minishell.git
cd minishell
make

Usage

./minishell
minishell$ echo "Hello, $USER"
Hello, ajami

minishell$ ls -la | grep .c | wc -l
42

minishell$ cat file.txt | sort | uniq >> output.txt

minishell$ export MY_VAR=42 && echo $MY_VAR
42

minishell$ echo $?
0

πŸ—οΈ Architecture

minishell/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ parsing/       # Lexer, tokenizer, AST builder
β”‚   β”œβ”€β”€ execution/     # Process management, pipes, redirections
β”‚   β”œβ”€β”€ builtins/      # Built-in command implementations
β”‚   β”œβ”€β”€ signals/       # Signal handling
β”‚   └── env/           # Environment variable management
β”œβ”€β”€ includes/
β”‚   └── minishell.h
β”œβ”€β”€ libft/
└── Makefile

🧠 Key Concepts

  • Lexing & Parsing β€” tokenizing input and building an executable command tree
  • fork() / execve() β€” spawning child processes and executing binaries
  • pipe() β€” inter-process communication via file descriptors
  • dup2() β€” redirecting stdin/stdout/stderr
  • waitpid() β€” synchronizing parent and child processes
  • readline β€” interactive input with persistent history

Made with ❀️ and a lot of segfaults at 42

About

🐚 A Unix shell built in C from scratch β€” parsing, processes, pipes and Bash behavior. 42 School.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors