As beautiful as a shell β A fully functional UNIX command-line interpreter built from scratch in C
Minishell is a project from the 42 School curriculum that challenges students to recreate a simplified version of Bash. This project demonstrates deep understanding of process management, file descriptors, signal handling, and parsing techniques β all implemented in pure C following strict coding standards.
This shell implementation handles real-world command-line scenarios including piping, redirections, environment variables, and built-in commands, providing a fully interactive shell experience.
- Interactive & Non-Interactive Modes β Full support for both terminal and scripted usage
- Command History β Navigate through previous commands using arrow keys (via GNU Readline)
- Signal Handling β Proper handling of
Ctrl+C,Ctrl+D, andCtrl+\signals
| Command | Description |
|---|---|
echo |
Display text with -n flag support |
cd |
Change directory with relative/absolute paths |
pwd |
Print current working directory |
export |
Set environment variables |
unset |
Remove environment variables |
env |
Display all environment variables |
exit |
Exit the shell with optional exit code |
- Input Redirection (
<) β Read input from a file - Output Redirection (
>) β Write output to a file - Append Mode (
>>) β Append output to a file - Here Document (
<<) β Read input until a delimiter is reached - Pipes (
|) β Chain multiple commands together
- Environment Variable Expansion β
$VARand$?(exit status) - Quote Handling β Single (
') and double (") quotes with proper escaping - Tilde Expansion β
~expands to home directory - Path Resolution β Commands searched in
$PATH
The project follows a modular architecture with clear separation of concerns:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MINISHELL β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββ β
β β LEXER β -> β PARSER β -> β EXECUTOR β -> β OUTPUT β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββ β
β β β β β
β βΌ βΌ βΌ β
β ββββββββββββ ββββββββββββ ββββββββββββ β
β β Tokens β β AST/ β β Process β β
β β Stream β β Cmds β β Mgmt β β
β ββββββββββββ ββββββββββββ ββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
minishell/
βββ include/ # Header files
β βββ minishell.h # Main data structures
β βββ lexer.h # Tokenization definitions
β βββ parser.h # Parsing functions
β βββ execute.h # Execution & builtins
β βββ garbage_collector.h
β βββ libft/ # Custom C library
β
βββ src/ # Source files
β βββ main.c # Entry point
β βββ shell.c # Shell loop & initialization
β β
β βββ lexer*.c # Tokenization (7 files)
β βββ parser*.c # Command parsing (4 files)
β βββ execute*.c # Command execution (2 files)
β βββ pipes*.c # Pipeline handling (2 files)
β βββ redirect.c # I/O redirections
β βββ heredoc*.c # Here document handling (7 files)
β β
β βββ builtin.c # Built-in dispatcher
β βββ echo.c # echo implementation
β βββ cd.c # cd implementation
β βββ pwd.c # pwd implementation
β βββ env.c # env implementation
β βββ export*.c # export implementation (3 files)
β βββ unset.c # unset implementation
β βββ exit.c # exit implementation
β β
β βββ env_*.c # Environment management
β βββ garbage*.c # Memory management
β βββ signals.c # Signal handling
β
βββ Makefile # Build configuration
The lexer breaks raw input into meaningful tokens:
Input: echo "Hello World" | grep Hello > output.txt
Tokens: [echo] ["Hello World"] [|] [grep] [Hello] [>] [output.txt]
The parser constructs a command list with proper structure:
- Commands are organized into nodes
- Redirections are attached to their respective commands
- Pipes create linked command chains
The executor processes the command structure:
- Single builtin: Executed in the main process (preserves environment changes)
- External commands: Forked into child processes
- Pipelines: Multiple processes connected via pipe file descriptors
A custom garbage collector tracks all allocations, ensuring clean memory handling throughout the shell's lifecycle.
- GCC or Clang compiler
- GNU Readline library
- Make build system
- Linux/macOS operating system
# Clone the repository
git clone https://github.com/AimonKied/42-minishell.git
# Navigate to project directory
cd 42-minishell
# Compile the project
make
# Run minishell
./minishellThe project compiles with strict flags to ensure code quality:
-Wall -Wextra -Werror
# Start the shell
./minishell
# Basic command execution
msh-1.0$ ls -la
# Pipeline example
msh-1.0$ cat file.txt | grep "pattern" | wc -l
# Redirections
msh-1.0$ echo "Hello" > output.txt
msh-1.0$ cat < input.txt >> output.txt
# Here document
msh-1.0$ cat << EOF
> Line 1
> Line 2
> EOF
# Environment variables
msh-1.0$ export MY_VAR="Hello World"
msh-1.0$ echo $MY_VAR
# Exit with status code
msh-1.0$ exit 42| System Call | Purpose |
|---|---|
fork() |
Create child processes |
execve() |
Execute external programs |
pipe() |
Create inter-process communication |
dup2() |
Redirect file descriptors |
wait()/waitpid() |
Synchronize parent/child processes |
signal() |
Handle system signals |
tcsetpgrp() |
Terminal process group management |
- Token List β Linked list of lexical tokens
- Command List β Linked list of command nodes with associated files
- Environment List β Linked list managing environment variables
- Heredoc List β Linked list for here document content
| Skill | Application |
|---|---|
| Process Management | Fork, exec, wait, pipes |
| Memory Management | Custom garbage collector, leak-free code |
| Signal Handling | SIGINT, SIGQUIT, proper terminal control |
| File I/O | Redirections, here documents |
| Parsing | Lexical analysis, tokenization, syntax validation |
| Data Structures | Linked lists, dynamic arrays |
| System Programming | POSIX compliance, Unix internals |
This project was developed as a collaborative effort at 42 Heilbronn:
- swied β Shell core, execution, builtins, heredocs
- vramacha β Lexer, parser, expansion, signals
This project is part of the 42 School curriculum. Feel free to explore and learn from the code!
Built with β€οΈ at 42 Heilbronn