A POSIX-compliant shell implementation built in Go as part of the CodeCrafters "Build Your Own Shell" Challenge. This shell supports command parsing, built-in commands, external program execution, I/O redirection, pipelines, command history, and tab completion.
- Command Parsing: Robust parsing with support for single quotes, double quotes, and backslash escaping
- Built-in Commands:
echo,exit,pwd,cd,type, andhistory - External Programs: Execute any program available in
$PATH - Interactive REPL: Read-Eval-Print Loop with raw terminal mode support
- I/O Redirection:
- Standard output redirection (
>,>>,1>,1>>) - Standard error redirection (
2>,2>>)
- Standard output redirection (
- Pipelines: Chain multiple commands with
|operator - Command History:
- Persistent history saved to
~/.shell_history(or$HISTFILE) - Navigate history with arrow keys (↑/↓)
- History commands:
history,history N,history -r FILE,history -w FILE,history -a FILE
- Persistent history saved to
- Tab Completion:
- Auto-complete commands from built-ins and
$PATH - Show all matches on double-tab
- Longest common prefix completion
- Auto-complete commands from built-ins and
- Single Quotes (
'...'): Preserve literal values of all characters - Double Quotes (
"..."): Preserve literal values except\,$,", and newline - Backslash Escaping: Escape special characters outside quotes or specific characters inside double quotes
- Go 1.25 or higher
- Unix-like operating system (Linux, macOS)
go build -o shell app/main.go./your_program.shOr directly:
go run app/main.go$ echo Hello, World!
Hello, World!
$ pwd
/home/user/current/directory
$ cd /tmp
$ pwd
/tmp
$ type echo
echo is a shell builtin
$ type ls
ls is /usr/bin/ls$ echo "Hello World"
Hello World
$ echo 'Single quotes preserve $PATH'
Single quotes preserve $PATH
$ echo "Double quotes expand \$PATH: $PATH"
Double quotes expand $PATH: /usr/bin:/bin
$ echo Hello\ \ \ World
Hello World$ echo "Hello" > output.txt
$ cat output.txt
Hello
$ echo "World" >> output.txt
$ cat output.txt
Hello
World
$ ls nonexistent 2> error.log
$ cat error.log
ls: cannot access 'nonexistent': No such file or directory$ echo "hello world" | tr a-z A-Z
HELLO WORLD
$ cat file.txt | grep pattern | wc -l
42
$ ls -la | grep ".go" | sort$ history
1 echo Hello
2 pwd
3 cd /tmp
$ history 2
2 pwd
3 cd /tmp
$ history -w myhistory.txt # Write history to file
$ history -r myhistory.txt # Read history from file
$ history -a myhistory.txt # Append new commands to file$ ec<TAB> # Completes to "echo "
$ his<TAB> # Completes to "history "
$ l<TAB><TAB> # Shows all commands starting with 'l'
ls ln less ...codecrafters-shell-go/
├── app/
│ └── main.go # Main shell implementation
├── codecrafters.yml # CodeCrafters configuration
├── go.mod # Go module definition
├── go.sum # Go dependencies checksums
├── your_program.sh # Shell script to run the program
└── README.md # This file
The parser handles complex quoting and escaping scenarios:
- Tracks quote state (single/double)
- Handles backslash escaping with context-aware rules
- Splits on whitespace outside quotes
- Preserves whitespace inside quotes
Uses raw terminal mode for advanced features:
- Character-by-character input processing
- ANSI escape sequence handling for arrow keys
- Tab completion with visual feedback
- Backspace and Ctrl+C support
Implements multi-command pipelines:
- Creates pipes between commands
- Handles both built-in and external commands
- Manages goroutines for concurrent execution
- Properly closes pipe file descriptors
- Loads history on startup from
$HISTFILEor~/.shell_history - Saves incrementally on exit
- Supports reading/writing/appending to custom files
- Tracks last appended index to avoid duplicates
This project is part of the CodeCrafters "Build Your Own Shell" challenge. To submit solutions:
git add .
git commit -m "Implement feature X"
git push origin masterTest output will be streamed to your terminal.
golang.org/x/term- Terminal control and raw mode supportgolang.org/x/sys- System calls for Unix-like systems
This project is created for educational purposes as part of the CodeCrafters challenge.
Built as part of the CodeCrafters "Build Your Own Shell" challenge, which teaches shell internals through hands-on implementation.