Skip to content

hariharanragothaman/unixshell

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

microshell

A Unix command-line interpreter written from scratch in C, with zero external dependencies.

Built as a deep dive into operating systems internals — process management, signal handling, file descriptors, and terminal I/O — using only POSIX system calls.

 _ __ ___ (_) ___ _ __ ___  ___| |__   ___| | |
| '_ ` _ \| |/ __| '__/ _ \/ __| '_ \ / _ \ | |
| | | | | | | (__| | | (_) \__ \ | | |  __/ | |
|_| |_| |_|_|\___|_|  \___/|___/_| |_|\___|_|_|

Features

  • Pipeline execution — chain commands with | (e.g. ls -la | grep src | wc -l)
  • I/O redirection<, >, >>, 2>, 2>> for stdin, stdout, stderr
  • Job control — background processes (&), jobs, fg, bg, Ctrl+Z to suspend
  • Signal handlingCtrl+C interrupts foreground process (not the shell), Ctrl+D for EOF
  • Command history — persistent across sessions, navigable with arrow keys
  • Line editing — cursor movement, word-delete (Ctrl+W), clear (Ctrl+L), kill-line (Ctrl+U/Ctrl+K)
  • Environment variables$VAR, ${VAR}, $? (last exit status), export, unset
  • Tilde expansion~/ resolves to $HOME
  • Quoting — double quotes (with variable expansion), single quotes (literal), backslash escapes
  • Command chaining; to run multiple commands sequentially
  • Built-in commandscd (with cd -), exit, help, history, jobs, fg, bg, export, unset
  • Colorized prompt — shows user@host:~/cwd$

Build

Requires a C11-compatible compiler (GCC or Clang) and a POSIX system (Linux, macOS, BSDs).

make            # build the binary
make debug      # build with AddressSanitizer + UBSan
make test       # run integration tests (24 tests)
make clean      # remove build artifacts

The binary is compiled with -Wall -Wextra -Werror -pedantic — zero warnings.

Usage

./microshell

Examples

# Pipelines
cat /var/log/syslog | grep error | sort | uniq -c | sort -rn | head

# I/O redirection
gcc -o program main.c 2> errors.txt
sort < input.txt > sorted.txt

# Background jobs
sleep 30 &
jobs
fg 1

# Environment variables
export EDITOR=vim
echo "Using $EDITOR"
echo "Last exit code: $?"

# Command chaining
mkdir build; cd build; cmake ..; make

Architecture

                    ┌─────────────┐
                    │   main.c    │  Initialization, cleanup
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
              ┌─────│   repl.c    │─────┐  Raw terminal mode,
              │     │             │     │  line editing, prompt
              │     └──────┬──────┘     │
              │            │            │
       ┌──────▼──────┐    │     ┌──────▼──────┐
       │  history.c   │    │     │  signals.c  │
       │              │    │     │             │
       └──────────────┘    │     └─────────────┘
                           │
                    ┌──────▼──────┐
                    │   lexer.c   │  Tokenization: quotes,
                    │             │  escapes, operators
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │  parser.c   │  Build command/pipeline
                    │             │  structs from tokens
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
              ┌─────│ executor.c  │─────┐
              │     └─────────────┘     │
              │                         │
       ┌──────▼──────┐          ┌──────▼──────┐
       │ builtins.c   │          │ pipeline.c  │  fork/exec,
       │              │          │             │  pipe(), waitpid()
       └──────────────┘          └──────┬──────┘
                                        │
                                 ┌──────▼──────┐
                           ┌─────│ redirect.c  │
                           │     └─────────────┘
                    ┌──────▼──────┐
                    │   jobs.c    │  Background process tracking
                    └─────────────┘

Module Breakdown

Module Lines Responsibility
shell.h 116 Core types: Token, Command, Pipeline, Job, ShellState
main.c 223 Entry point, safe allocators, variable/tilde expansion
repl.c 373 REPL loop, raw terminal mode, line editor with history nav
lexer.c 151 Tokenizer — handles "quotes", 'literals', \escapes, operators
parser.c 191 Builds Pipeline/Command structs from token stream
executor.c 28 Orchestrates pipeline execution across semicolons
pipeline.c 161 fork()/execvp(), pipe plumbing, process groups
builtins.c 206 9 built-in commands (cd, exit, help, history, jobs, fg, bg, export, unset)
redirect.c 58 dup2() based file descriptor redirection
signals.c 76 Signal disposition for shell vs child processes
jobs.c 187 Job table management, foreground/background control
history.c 104 Persistent command history with file I/O

~2000 lines of C — no external dependencies, pure POSIX.

Key System Calls Used

Category System Calls
Process fork(), execvp(), waitpid(), _exit(), setpgid(), getpid()
Pipes pipe(), dup2(), close()
File I/O open(), read(), write(), fopen(), fgets()
Signals sigaction(), sigprocmask(), kill(), signal()
Terminal tcsetpgrp(), tcgetattr(), tcsetattr(), isatty()
Environment getenv(), setenv(), unsetenv(), getcwd(), chdir()

Design Decisions

  • No readline/ncurses — line editing and raw terminal handling implemented from scratch to demonstrate low-level terminal I/O
  • C11 standard — modern C with designated initializers and strict compilation flags
  • Defensive memory managementxmalloc/xstrdup wrappers that abort on failure; every allocation has a matching free
  • Process group isolation — each pipeline gets its own process group for correct signal delivery and job control
  • SIGCHLD blocking — foreground pipelines block SIGCHLD to prevent the async handler from racing with waitpid()

Testing

24 integration tests covering:

  • Built-in commands (cd, exit, help, export/unset, $?)
  • Multi-stage pipes
  • I/O redirection (input, output, append, stderr)
  • Background jobs
make test

License

MIT — see LICENSE.

About

An UNIX based command line interpreter for User-­‐OS interactions using C

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors