diff --git a/README.md b/README.md index 6ac1acf..82313c6 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,117 @@ # bash-for-windows -A fully functional bash shell for Windows, written in Go. Run bash commands and scripts natively on Windows without WSL, Cygwin, or MSYS2. +A bash-compatible shell for Windows, written in Go. Runs natively as a single `.exe` — no WSL, Cygwin, or MSYS2 required. + +## Install + +1. Download the latest release zip and extract it. +2. Double-click **`install.bat`**. + +That's it. The installer: +- Copies `bash.exe` to `%LOCALAPPDATA%\Programs\BashForWindows\` +- Adds it to your user **PATH** +- Registers a **"Bash for Windows"** profile in Windows Terminal so it shows up in the `+` dropdown + +```powershell +# Optional flags +.\install.ps1 -InstallDir "C:\Tools\bash" # custom install path +.\install.ps1 -NoTerminal # skip Windows Terminal profile +.\install.ps1 -Uninstall # clean removal +``` ## Features -- **Interactive shell** with prompt (`bash$`) -- **Built-in commands**: cd, pwd, echo, exit, export, source, alias, type -- **Built-in coreutils**: ls, cat, grep, sort, wc, head, find, cp, mv, rm, mkdir, touch, clear -- **Command chaining**: `&&`, `||`, `;` -- **Pipes**: `|` between commands -- **Variable expansion**: `$NAME`, `${NAME}` -- **Variable assignment**: `NAME=VALUE command` -- **Single & double quotes**: `'literal'`, `"$variable"` -- **Script execution**: `bash-windows script.sh` or `-c 'commands'` -- **No dependencies** — single `.exe` file, runs on any Windows x86-64 +### Shell language +- **Control flow** — `if/elif/else/fi`, `for/do/done`, `while/until` +- **Functions** — `name() { ... }` and `function name { ... }`, with `local`/`return` +- **Arithmetic** — `$(( expr ))`, `$((i + 1))`, `$((n % 2))` +- **Command substitution** — `$(cmd)`, including pipelines: `x=$(echo foo | tr a-z A-Z)` +- **Variable expansion** — `$VAR`, `${VAR}`, `${VAR:-default}`, `${VAR:=val}`, `${#VAR}`, `${VAR%suffix}`, `${VAR#prefix}` +- **Glob expansion** — `*.txt`, `src/**` +- **Tilde expansion** — `~/Documents` +- **Quotes** — single `'literal'`, double `"with $vars"`, backslash escapes +- **Inline comments** — `echo hello # this is ignored` + +### I/O +- **Pipelines** — `cmd1 | cmd2 | cmd3` +- **Redirection** — `>`, `>>`, `<`, `2>`, `2>&1`, `&>` +- **Background jobs** — `cmd &` +- **Command chaining** — `&&`, `||`, `;` + +### Interactive +- **Command history** with arrow keys (saved to `~/.bash_history`) +- **Tab completion** for commands and file paths +- **Multi-line input** — `if`/`for`/`while`/functions continue on the next line +- **Prompt** shows current directory and last exit code when non-zero + +### Built-in commands +| Category | Commands | +|----------|----------| +| Shell | `cd`, `pwd`, `echo`, `exit`, `export`, `set`, `unset`, `source`/`.`, `alias`, `unalias`, `type`, `command`, `which`, `env` | +| Control | `true`, `false`, `test`/`[`, `break`, `continue`, `return`, `shift`, `read`, `printf` | +| Variables | `declare`, `local` | +| Files | `ls`, `cat`, `cp`, `mv`, `rm`, `mkdir`, `touch`, `find`, `stat`, `basename`, `dirname` | +| Text | `grep`, `sed`, `awk`, `sort`, `uniq`, `wc`, `head`, `tail`, `cut`, `tr`, `tee`, `xargs` | +| System | `date`, `sleep`, `clear`, `jobs` | ## Usage ``` -bash-windows # Interactive mode -bash-windows -c 'echo hello' -bash-windows script.sh +bash # interactive shell +bash -c 'echo hello' # run a command string +bash script.sh # run a script file +bash script.sh arg1 # pass arguments ($1, $2, ...) ``` ### Examples -``` -bash$ echo "Hello from bash-for-windows!" -bash$ ls -la -bash$ cd /tmp && pwd -bash$ cat file.txt | grep pattern | wc -l -bash$ name="Luffy" && echo $name -bash$ mkdir -p project/src && touch project/src/main.go +```bash +# Variables and arithmetic +name="World" +echo "Hello $name" +echo $((40 + 2)) + +# Loops and functions +is_even() { + if [ $(($1 % 2)) -eq 0 ]; then return 0; else return 1; fi +} +for n in 1 2 3 4 5 6; do + if is_even $n; then echo "$n is even"; fi +done + +# Pipelines and redirection +cat /etc/hosts | grep localhost | wc -l +find . -name "*.go" | xargs grep -l "TODO" > todo_files.txt +echo "result=$(date)" >> log.txt ``` -## Building +## Build from source Requires Go 1.21+. ```bash -# Linux -./build.sh - -# Manual -go build -o build/bash-windows . - -# Windows cross-compile -GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o build/bash-windows.exe . +./build.sh # builds Linux debug + Windows .exe into build/ +./build.sh --release # also creates release/ folder ready to distribute ``` -## Project Structure +```bash +# Manual cross-compile +GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o bash.exe . +``` + +## Project layout ``` -cmd/bash/ - Shell entry point -internal/shell/ - Shell engine (parser, executor, builtins, coreutils) -build/ - Compiled binaries +cmd/bash/ entry point, readline REPL +internal/shell/ + shell.go Execute, parseBlocks, splitStatements, IsIncomplete + expand.go expandWord, tokenize, arithmetic, glob + exec.go pipelines, redirections, external commands + control.go if/for/while/until, function define/call + builtins.go all built-in commands and coreutils +install.ps1 Windows installer (PATH + Windows Terminal profile) +install.bat double-click wrapper for install.ps1 +build.sh build script ``` ## License