A lightweight, POSIX-compliant command-line interpreter built from scratch in C. This project demonstrates core operating-system principles — process management, inter-process communication, file descriptor manipulation, and manual memory management — implemented without relying on any existing shell.
- Features Implemented
- Architecture & System Calls
- Getting Started
- Manual Testing Examples
- Future Work / Roadmap
| Feature | Details |
|---|---|
| Process execution | Executes standard system commands (ls, grep, cat, etc.) by searching the PATH environment variable |
Built-in: cd |
Changes the shell's current working directory |
Built-in: pwd |
Prints the current working directory |
Built-in: history |
Displays a ring buffer of recently executed commands |
Built-in: exit |
Safely terminates the shell and frees all allocated memory |
| Output redirection | Truncating (>) and appending (>>) to a file |
| Input redirection | Reading command input from a file (<) |
The shell runs an infinite REPL (Read–Eval–Print Loop), split into distinct modules:
-
Parser (
parser.c) Reads raw input withgetline()(avoids fixed-size buffer overflows) and tokenizes it, separating redirection symbols (>,>>,<) from the command's own arguments. -
Executor (
executor.c) Handles process creation:fork()clones the parent process.execvp()replaces the child's memory image with the target executable.waitpid()blocks the parent until the child finishes, preventing zombie processes.
-
File descriptor redirection When redirection is detected, the child opens the target file with
open()and usesdup2()to overwriteSTDIN_FILENO(0) orSTDOUT_FILENO(1) before callingexecvp()— rerouting I/O transparently, with no changes needed in the executed program itself.
- GCC
- GNU Make
- A Unix/Linux environment (or WSL on Windows) — this project relies on POSIX system calls
# Clone the repository
git clone https://github.com/RahulBiswas224/CShell.git
cd CShell
# Compile using the included Makefile
make
# Run the shell
./myshellmake cleanmyshell> ls -la
myshell> echo "Hello World" > output.txt
myshell> cat < output.txt
myshell> echo "Appending text" >> output.txt
myshell> history
myshell> exit
The architecture was designed to be extensible. Planned next:
- Pipes (
|) — wire one process's stdout directly into another's stdin usingpipe(), e.g.ls -la | grep .c - Background jobs (
&) — run processes asynchronously, with a zombie-reaping loop usingwaitpid()and theWNOHANGflag so the shell isn't blocked waiting on background children - Signal handling — catch
SIGINT(Ctrl+C) andSIGTSTP(Ctrl+Z) so they interrupt the running child process without killing the shell itself
Built by Rahul Biswas as a systems-programming project ahead of technical interviews focused on C, operating systems, and process management.