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.
- Interactive prompt with command history
- Command execution via
PATHresolution - 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 |
- GCC
- Make
- Unix-based OS (Linux / macOS)
readlinelibrary
# On Ubuntu/Debian
sudo apt install libreadline-devgit clone https://github.com/YourName/minishell.git
cd minishell
make./minishellminishell$ 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 $?
0minishell/
βββ 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
- Lexing & Parsing β tokenizing input and building an executable command tree
fork()/execve()β spawning child processes and executing binariespipe()β inter-process communication via file descriptorsdup2()β redirecting stdin/stdout/stderrwaitpid()β synchronizing parent and child processesreadlineβ interactive input with persistent history