A lightweight, POSIX-compliant UNIX shell written in C from scratch. This project demonstrates core operating system concepts such as process creation, inter-process communication (IPC), file descriptor manipulation, and robust signal handling. It closely mirrors the behavior of standard shells like bash or sh while remaining modular and heavily documented.
- Execution: Runs standard foreground and background (
&) processes. - Pipelining: Supports unlimited chained pipelines (e.g.,
ls -l | grep src | wc -l). - I/O Redirection: Handles input (
<), output (>), and append (>>) file redirection. - Built-in Commands:
cd,exit, andhistory. - Signal Handling: Gracefully handles
SIGINT(Ctrl+C) without crashing, and automatically reaps background zombie processes viaSIGCHLD.
The shell is built with a clean, modular architecture separating concerns across dedicated C modules:
shell.c: The main REPL (Read-Eval-Print Loop).parser.c: Parses raw string input into structuredCommanddata objects.execute.c: Handles single-commandfork()andexecvp()logic.pipe.c: OrchestratesN-1pipes forNcommands, chaining standard I/O streams.redirect.c: Manages file opens anddup2()descriptor mapping.signals.c: Installs isolated signal handlers and manages state restoration for child processes.builtin.c&history.c: Implements internal commands and memory-managed command history.
linux-mini-shell/
├── Makefile
├── README.md
└── src/
├── builtin.c / builtin.h
├── command.c / command.h
├── execute.c / execute.h
├── history.c / history.h
├── main.c
├── parser.c / parser.h
├── pipe.c / pipe.h
├── redirect.c / redirect.h
├── shell.c / shell.h
└── signals.c / signals.h
This project extensively utilizes UNIX system calls to interface directly with the kernel:
- Process Management:
fork(),execvp(),waitpid() - IPC & Pipes:
pipe(),dup2() - File I/O:
open(),close(),read(),write() - Signals:
signal(),sigaction(),kill() - Environment:
chdir()
To build and run the project locally, ensure you have gcc and make installed.
# Clone the repository
git clone https://github.com/HarshEvolves/linux-mini-shell.git
cd linux-mini-shell
# Build the project
make
# Run the shell
make run
# OR manually run: ./build/minishellStandard Execution & Backgrounding
myshell$ ls -la
myshell$ sleep 10 &
[12345]Unlimited Pipelining
myshell$ cat README.md | grep "C" | wc -lI/O Redirection
myshell$ echo "Hello, World!" > output.txt
myshell$ cat < output.txt >> history.logSignal Resilience
myshell$ sleep 10
^C # Kills the sleeping child, but returns cleanly to the shell prompt
myshell$ - Process Forking & Execution: Replacing a child process image with a new executable while preserving parent state.
- Zombie Process Reaping: Using non-blocking
waitpid(WNOHANG)inside aSIGCHLDhandler to prevent resource leaks. - File Descriptor Chaining: Routing
stdoutof one process into thestdinof another using kernel pipes anddup2(). - Interruption Safety: Safely handling
EINTRerrors from blocking calls likegetline()andwaitpid()when signals are caught.
- Logical Operators: Support for
&&and||. - Job Control: Implementation of
fg,bg, andjobscommands usingSIGTSTP. - Quoting & Escaping: Support for parsing strings containing spaces inside double/single quotes.
- Environment Variables: Support for expanding
$VARvariables andexport.
Building this shell provided deep, hands-on experience with systems programming in C, kernel-level process management, memory safety (avoiding leaks across forks), and designing robust architectures that can safely handle asynchronous OS signals.
