A compact Unix shell written in C as part of the 42 curriculum.
The project recreates a practical subset of Bash and focuses on process creation, file descriptors, pipes, signals, parsing, environment management, and command execution.
Minishell reads a command line, converts it into an internal command representation, expands variables, applies redirections, builds pipelines, and executes built-in or external commands.
The implementation is divided into several stages:
input -> lexer -> parser -> expansion -> redirections -> execution
- Interactive prompt powered by GNU Readline
- Command history
- Execution of programs through absolute, relative, or
PATH-resolved paths - Pipelines using
pipe,fork,dup2, andexecve - Input and output redirections:
<input redirection>output redirection>>append redirection<<heredoc
- Environment-variable expansion, including
$? - Single-quote and double-quote handling
- Bash-like handling of
Ctrl-C,Ctrl-D, andCtrl-\ - Exit-status propagation
- Built-in commands:
echowith-ncdpwdexportunsetenvexit
The interactive loop reads user input with readline, stores non-empty commands in history, and rejects unsupported or incomplete syntax before execution.
The lexer scans the input while preserving quoted sections and identifies operators such as pipes and redirections.
Tokens are converted into command structures containing:
- executable name
- argument vector
- redirections
- pipeline position
- heredoc information
The expansion stage resolves environment variables and the previous command's exit status. Expansion behavior depends on quote context.
The executor prepares heredocs and redirections, creates pipelines, forks child processes, resolves executable paths, and collects exit statuses.
Built-ins that must modify shell state, such as cd, export, and unset, are executed in the parent process when they are not part of a pipeline.
Signal behavior changes depending on whether the shell is waiting for input, executing a child process, or processing a heredoc.
GNU Readline must be installed.
On Debian or Ubuntu:
sudo apt install libreadline-devOn macOS with Homebrew:
brew install readlineCompile the project:
makeClean object files:
make cleanRemove all generated files:
make fcleanRebuild:
make reStart the shell:
./minishellExample commands:
echo "Hello, $USER"
pwd
cd ..
ls -la | grep minishell
cat < input.txt | wc -l > result.txt
echo "$?"Exit with:
exitor press Ctrl-D on an empty prompt.
- Unix process lifecycle
- Parent and child process coordination
- File-descriptor management
- Inter-process communication
- Signal handling
- Lexical analysis and parsing
- Dynamic-memory ownership
- Environment-variable management
- Error handling and exit codes
This project implements the behavior required by the Minishell assignment and is not intended to be a complete Bash replacement.
Features such as logical operators, command grouping, wildcard expansion, job control, and scripting may be outside the implemented scope unless added separately.
Useful test categories include:
- simple and invalid commands
- quoted and unquoted arguments
- environment expansion
- chained pipelines
- all redirection types
- permission and missing-file errors
- built-ins inside and outside pipelines
- signal behavior
- exit-status comparison with Bash
- memory-leak checks
For behavioral verification, commands can be run in both Bash and Minishell and their output and exit status compared.
This repository is presented as a systems-programming project demonstrating practical knowledge of C, Unix processes, pipes, signals, parsing, and shell execution.