A lightweight Unix shell written in C, built as part of the 42 curriculum.
This project focuses on building a real interactive shell from scratch: lexical analysis, parsing, expansion, command tree construction, process execution, pipes, redirections, heredocs, builtin commands, and signal handling.
minishell is a systems programming project that demonstrates:
- Process control with
fork,execve,waitpid - File descriptor orchestration for pipes and redirections
- Stateful parsing pipeline (tokenize -> expand -> retoken -> combine -> grammar -> command tree)
- Environment management in user space (copy/update/unset shell env)
- Interactive terminal behavior with
readline+ POSIX signals
For recruiters, this is a practical example of low-level engineering, debugging discipline, and modular C design.
- Interactive prompt with history (
readline/add_history) - Builtins:
cdecho(supports-n)envexitexportpwdunset
- External command execution via
execve PATHresolution for executables- Pipelines (
|) - Redirections:
- input:
< - output:
> - append:
>> - heredoc:
<<
- input:
- Quote-aware tokenization (
'and") - Environment variable expansion:
$VAR$?
- Basic syntax validation (pipes/redirection placement)
- Signal behavior for interactive shell and child processes
The codebase is split into focused modules:
src/main: shell lifecycle, init/cleanup, interactive loop, signal setupsrc/parse: tokenization, expansion, grammar checks, command graph construction, heredoc handlingsrc/execute: builtin dispatch, process creation, pipe orchestration, redirection setup, command path resolutionsrc/builtins: implementations of shell builtinslibft: custom utility library used by the shellinc/minishell.h: shared data structures and function contracts
Core runtime structs:
t_shell: global shell state (env, parser state, command tree, last exit code)t_state: current input + token streamt_xnode: command node in pipeline linked list (argv+ redirections)t_redir: redirection metadata
For each input line:
- Tokenize input into words/operators/quoted values
- Expand variables where allowed
- Remove empty tokens, retoken expanded values when needed
- Combine adjacent quote/word fragments into final arguments
- Validate grammar (pipe and redirection sanity checks)
- Build command nodes (
t_xnodelinked list) - Pre-process heredocs
- Execute as:
- single builtin in parent shell process when possible
- otherwise pipeline of child processes
- Linux (or Unix-like environment)
cc- GNU Make
readlinedevelopment library
On Debian/Ubuntu:
sudo apt-get update
sudo apt-get install build-essential libreadline-devmakeUseful targets:
make clean
make fclean
make re
make debug./minishellreadline and add_history can report known leaks from the library itself. If you want to suppress these leaks, create a suppression file called readline_suppress.supp. Content:
{
readline_leak
Memcheck:Leak
...
fun:readline
}
{
add_history_leak
Memcheck:Leak
...
fun:add_history
}Run minishell with Valgrind and suppressions:
valgrind \
--leak-check=full \
--show-leak-kinds=all \
--track-origins=yes \
--suppressions=readline_suppress.supp \
./minishellIf you run the command from another directory, pass the absolute path to the suppression file:
valgrind --suppressions=/home/htharrau/0Projects/3_rank/minishell/minishell/readline_suppress.supp ./minishellecho hello world
pwd
export PROJECT=mini
echo $PROJECT
cat < infile_big | grep 42 | wc -l
echo line >> out.txt
cat << EOF
value is $PROJECT
EOFThis implementation intentionally stays within a scoped feature set and currently does not include:
- Logical operators (
&&,||) - Wildcard/glob expansion (
*) - Subshells (
(...)) - Command substitution (
$(...)) - Full POSIX compatibility edge cases
- Advanced
echoflags beyond basic-n cdwithout argument (HOME) behavior
- Modular source organization by responsibility
- Dedicated cleanup paths for parser/execution structures
- Clear exit code propagation from children and builtins
- Defensive handling for allocation and syscall failures
This repository is an educational shell implementation created to practice low-level Unix programming and interpreter-style architecture.