A custom Unix shell built from scratch in C using POSIX system calls and Linux process management primitives. This project recreates the core functionality of a Unix shell, including command execution, parsing, piping, I/O redirection, job control, background execution, and signal handling.
The primary objective of this project was to gain hands-on experience with Operating Systems concepts such as process creation, inter-process communication, file descriptor management, signals, and shell architecture.
- Interactive Unix-style shell prompt
- Displays username, hostname, and current working directory
- Supports home directory (
~) expansion in the prompt - Continuously accepts and executes user commands
The shell includes a dedicated parser capable of interpreting complex command structures.
Supported syntax includes:
- Multiple command arguments
- Sequential execution (
;) - Background execution (
&) - Multi-stage pipelines (
|) - Input redirection (
<) - Output redirection (
>) - Output append redirection (
>>)
The parser validates command syntax before execution and separates parsing from execution using a modular architecture.
The shell executes external commands using Linux process management primitives.
Implemented features include:
- Child process creation
- Foreground process execution
- Background process execution
- Process synchronization
- Child process cleanup
- Process tracking
System calls used:
fork()execvp()wait()waitpid()
Supports multi-stage command pipelines such as:
cat file.txt | grep hello | sortImplementation uses:
pipe()dup2()- Multiple child processes
- File descriptor management
Supports:
command < input.txtcommand > output.txtcommand >> output.txtImplemented using:
open()dup2()close()
Supports combining pipes and redirection.
Supports execution of multiple commands in order using:
command1 ; command2 ; command3Each command completes before the next one begins.
Supports background jobs using:
sleep 10 &Features include:
- Non-blocking execution
- Background process tracking
- Automatic cleanup of completed jobs
- Interactive shell remains responsive
Supports Unix job management through built-in commands:
fgbgactivities
Capabilities include:
- Bringing jobs to the foreground
- Resuming stopped jobs
- Listing active jobs
- Maintaining process state information
The shell correctly handles interactive Unix signals.
Implemented support for:
SIGINT(Ctrl+C)SIGTSTP(Ctrl+Z)
The shell forwards signals to foreground processes while ensuring the shell itself continues running.
Changes the current working directory.
Supports:
- Home directory
- Parent directory
- Previous directory
- Relative paths
- Absolute paths
Lists directory contents.
Supports:
- Hidden files
- Multiple flags
- Directory traversal
Persistent command history.
Supports:
- Viewing history
- Clearing history
- Re-executing previous commands
Displays currently running or stopped processes managed by the shell.
Sends Unix signals to a specified process.
Moves a background or stopped process to the foreground.
Resumes a stopped process in the background.
This project provides practical implementation of the following Operating Systems concepts:
- Unix Shell Architecture
- POSIX System Programming
- Process Creation
- Process Synchronization
- Process Control
- Job Control
- Inter-Process Communication
- Pipes
- File Descriptor Management
- Input/Output Redirection
- Signal Handling
- Background Process Management
- Command Parsing
- Modular Systems Programming
The implementation makes extensive use of POSIX system calls, including:
| System Call | Purpose |
|---|---|
fork() |
Create child processes |
execvp() |
Execute external commands |
wait() |
Wait for child processes |
waitpid() |
Synchronize and manage child processes |
pipe() |
Create communication channels between processes |
dup2() |
Redirect standard input and output |
open() |
Open files for redirection |
close() |
Close file descriptors |
chdir() |
Change working directory |
getcwd() |
Retrieve current working directory |
kill() |
Send signals to processes |
sigaction() |
Install signal handlers |
shell/
├── Makefile
├── include/
│ └── shell.h
└── src/
├── activities.c
├── background.c
├── builtin.c
├── executor.c
├── hop.c
├── job_control.c
├── log.c
├── main.c
├── parser.c
├── ping.c
├── process_mgmt.c
├── prompt.c
├── reveal.c
├── sequential.c
└── signals.c
| File | Responsibility |
|---|---|
main.c |
Shell initialization and main execution loop |
prompt.c |
Displays the interactive shell prompt |
parser.c |
Parses user commands and shell operators |
executor.c |
Executes parsed commands |
builtin.c |
Dispatches built-in shell commands |
hop.c |
Directory navigation implementation |
reveal.c |
Directory listing functionality |
log.c |
Persistent command history |
background.c |
Background process execution and tracking |
process_mgmt.c |
Process bookkeeping and management |
job_control.c |
Foreground/background job management |
signals.c |
Signal registration and handling |
activities.c |
Lists active jobs managed by the shell |
ping.c |
Sends signals to processes |
sequential.c |
Sequential command execution |
Compile the project using:
make allRun the shell:
./shell.outreveal
hop ..
hop ~
cat file.txt
cat input.txt > output.txt
sort < input.txt
cat file.txt | grep hello
cat file.txt | grep hello | sort
sleep 15 &
activities
fg
bg
log
log execute 2Some of the major implementation challenges included:
- Designing a modular command parser
- Handling multiple child processes simultaneously
- Implementing multi-stage pipelines
- Managing file descriptors during redirection
- Handling Unix signals without terminating the shell
- Implementing reliable foreground and background job control
- Synchronizing concurrent processes
- Maintaining a persistent command history
This project strengthened my understanding of:
- Linux internals
- POSIX programming
- Unix process lifecycle
- Process synchronization
- Shell implementation
- Job scheduling
- Signal handling
- File descriptor management
- Inter-process communication
- Modular software design in C
Potential enhancements include:
- Environment variable expansion
- Wildcard (
*) expansion - Command auto-completion
- Alias support
- Command substitution
- Quoted string handling
- Shell scripting support
- Improved error reporting
- Configuration file support
- Plugin architecture
- Language: C
- Platform: Linux
- Standards: POSIX
- Build System: Make
- Core Concepts: Operating Systems, Unix System Programming, Process Management, Inter-Process Communication, Signals, File Systems