Skip to content

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Shell Implementation in Go

A POSIX-like shell built from scratch in Go as part of the CodeCrafters "Build Your Own Shell" Challenge. This project implements a functional shell with a REPL, builtin commands, PATH resolution, and external program execution.

Features Implemented

Builtin Commands

Command Description
exit Exits the shell with a clean return
echo Outputs arguments to stdout, preserving spacing
type Identifies if a command is a shell builtin or locates it in PATH

Core Functionality

  • REPL (Read-Eval-Print Loop): Continuous shell prompt that reads user input, processes commands, and displays output
  • Invalid Command Handling: Gracefully handles unknown commands with appropriate error messages
  • PATH Resolution: Searches directories in $PATH to locate executable files
  • External Program Execution: Runs any executable found in PATH with full argument passing and I/O handling

Technical Implementation

Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Shell REPL Loop                         │
│                    ($ prompt, input)                        │
├─────────────────────────────────────────────────────────────┤
│                    Command Parser                           │
│              (tokenizes input into cmd + args)              │
├──────────────────────┬──────────────────────────────────────┤
│   Builtin Commands   │        External Programs             │
│  (exit, echo, type)  │   (PATH lookup + exec.Command)       │
└──────────────────────┴──────────────────────────────────────┘

Key Components

  • Input Handling: Buffered reader with proper EOF and error handling
  • Command Parsing: Splits input into command and arguments using strings.Fields
  • Builtin Registry: Map-based lookup for O(1) builtin command identification
  • PATH Search: Iterates through PATH directories, checking file existence and executable permissions
  • Process Execution: Uses Go's os/exec package with stdin/stdout/stderr passthrough

PATH Resolution Algorithm

func findExecutable(cmd string) (string, bool) {
    // 1. Get PATH environment variable
    // 2. Split into directories by OS path separator
    // 3. For each directory, check if cmd exists and is executable
    // 4. Return full path if found, empty string otherwise
}

The executable check verifies the file's mode bits (mode&0111 != 0) to ensure it has execute permissions.

Completed Challenge Stages

Base Challenges (8/8)

  • Print a prompt - Display $ and wait for input
  • Handle invalid commands - Return <cmd>: command not found
  • Implement a REPL - Continuous command loop
  • Implement exit - Clean shell termination
  • Implement echo - Output arguments to stdout
  • Implement type - Identify builtin commands
  • Locate executable files - Search PATH for executables
  • Run a program - Execute external programs with arguments

Running the Shell

# Start the shell
./your_program.sh

# Or run directly with Go
go run app/main.go

Example Usage

$ echo Hello World
Hello World

$ type echo
echo is a shell builtin

$ type cat
cat is /bin/cat

$ type nonexistent
nonexistent: not found

$ cat README.md
# (displays file contents)

$ exit

Project Structure

.
├── app/
│   └── main.go      # Complete shell implementation
├── your_program.sh  # Shell startup script
└── README.md

Skills Demonstrated

  • Systems Programming: Building a shell that interfaces directly with the operating system
  • Process Management: Spawning and managing child processes with proper I/O handling
  • Environment Variables: Parsing and utilizing PATH for executable resolution
  • Input Parsing: Tokenizing user input into commands and arguments
  • Error Handling: Graceful handling of invalid commands, missing files, and execution errors

Built as part of the CodeCrafters challenge series.

About

A POSIX-like shell built from scratch in Go as part of the CodeCrafters "Build Your Own Shell" Challenge. This project implements a functional shell with a REPL, builtin commands, PATH resolution, and external program execution.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages