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.LookPathsearches$PATH, and that external commands fork automatically viaexec.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 functionalityshlex: Lexer & tokenizationparse: Command parsing
Using an external library for advanced features
- Used ergochat/readline to implement tab completion and shell history