Back to Projects

OhmyGoSh

Go ergochat/readline

Project Overview

OhmyGoSh is a custom Unix shell implementation written in Go (almost) from scratch

Features

  • Built-in commands: exit, echo, type, pwd, cd (with ~ expansion)
  • Pipes: Chain commands with |
  • Redirection: stdout (>, >>) and stderr (2>, 2>>)
  • External commands: Execute any binary in PATH
  • Tab completion: Builtins, PATH executables, and file paths
  • Interactive: Command history with arrow keys

What I Learned

How REPLs, commands, shell operators, and PATH work

  • Learned how a read-print loop works, and the difference between handling Ctrl+C (interrupt) vs. Ctrl+D (exit)
  • Learned that commands run in-process, unlike external binaries
  • Learned how exec.LookPath searches $PATH, and that external commands fork automatically via exec.Command
  • Learned that os.Pipe() creates connected file descriptors, and closing write end signals EOF to reader
  • Because builtins run in the same process they can’t block on stdin - goroutines solve this by running them concurrently

Optimising lookups by using the right data structure

  • What started as bunch of if-else statements evolved into a Dispatch map (hash map) where the command is the key and the function the command triggers is the value map[string]CommandFunc. This gives O(1) lookup and makes adding new commands trivial

Separation of concerns

  • As the project grew I extracted related code as packages each has a single responsibility:
    • shell: Core functionality
    • shlex: Lexer & tokenization
    • parse: Command parsing

Using an external library for advanced features

  • Used ergochat/readline to implement tab completion and shell history