{"id":47827901,"url":"https://github.com/standardbeagle/ps-bash","last_synced_at":"2026-05-23T22:02:05.570Z","repository":{"id":348866174,"uuid":"1200151021","full_name":"standardbeagle/ps-bash","owner":"standardbeagle","description":"Bash commands for PowerShell — real flags, real output, typed objects underneath. 67 commands, 775 tests, cross-platform.","archived":false,"fork":false,"pushed_at":"2026-05-17T04:24:35.000Z","size":12161,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-17T04:39:14.321Z","etag":null,"topics":["bash","cli","cross-platform","devops","linux","macos","pipeline","powershell","powershell-module","shell","typed-objects","windows"],"latest_commit_sha":null,"homepage":"https://standardbeagle.github.io/ps-bash/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/standardbeagle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-03T04:59:40.000Z","updated_at":"2026-05-17T04:24:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"3d5e7d4c-b0da-4db3-97f8-7d523cd141a6","html_url":"https://github.com/standardbeagle/ps-bash","commit_stats":null,"previous_names":["standardbeagle/ps-bash"],"tags_count":40,"template":false,"template_full_name":null,"purl":"pkg:github/standardbeagle/ps-bash","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/standardbeagle%2Fps-bash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/standardbeagle%2Fps-bash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/standardbeagle%2Fps-bash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/standardbeagle%2Fps-bash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/standardbeagle","download_url":"https://codeload.github.com/standardbeagle/ps-bash/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/standardbeagle%2Fps-bash/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33413623,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T18:09:33.147Z","status":"ssl_error","status_checked_at":"2026-05-23T18:09:31.380Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","cli","cross-platform","devops","linux","macos","pipeline","powershell","powershell-module","shell","typed-objects","windows"],"created_at":"2026-04-03T20:02:45.532Z","updated_at":"2026-05-23T22:02:05.556Z","avatar_url":"https://github.com/standardbeagle.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PsBash\n\n**Real bash commands on Windows. No WSL, Git Bash, or Cygwin required.**\n\nPsBash transpiles bash to PowerShell — `rm -rf`, `ls -la`, `grep -r`, `sort -k3` all work natively. Every command returns **typed .NET objects** while producing bash-identical text output. Includes a standalone shell binary that AI coding agents (Claude Code, OpenCode, GitHub Copilot) can use as a drop-in bash replacement.\n\n[![CI](https://github.com/standardbeagle/ps-bash/actions/workflows/ci.yml/badge.svg)](https://github.com/standardbeagle/ps-bash/actions/workflows/ci.yml)\n[![PSGallery](https://img.shields.io/powershellgallery/v/PsBash.svg?label=PSGallery)](https://www.powershellgallery.com/packages/PsBash)\n[![Tests](https://img.shields.io/badge/tests-857%20passing-brightgreen.svg)](#testing)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)](#cross-platform)\n\n## Quick Install\n\n**As a PowerShell module:**\n\n```powershell\nInstall-Module PsBash\n```\n\n**As a standalone shell binary (no .NET runtime required):**\n\n```powershell\n# Windows\niwr https://raw.githubusercontent.com/standardbeagle/ps-bash/main/install.ps1 | iex\n\n# Linux / macOS\ncurl -fsSL https://raw.githubusercontent.com/standardbeagle/ps-bash/main/install.sh | bash\n```\n\n\u003cpicture\u003e\n  \u003csource srcset=\"docs/assets/demo.webp\" type=\"image/webp\"\u003e\n  \u003cimg src=\"docs/assets/demo.gif\" alt=\"ps-bash demo showing typed pipeline objects\" width=\"800\"\u003e\n\u003c/picture\u003e\n\n## Why PsBash?\n\nPowerShell ships aliases for `ls`, `cat`, `sort`, `rm` — but they're lies. `rm -rf` fails. `ls -la` fails. `sort -k3 -rn` fails. They're `Get-ChildItem`, `Get-Content`, and `Sort-Object` wearing a disguise, rejecting every bash flag you throw at them.\n\nPsBash makes the flags work — and goes further. Every command returns **typed .NET objects** while producing bash-identical text output.\n\n### 1. Parse process data without awk\n\n```powershell\n# Before: string parsing\nPS\u003e Get-Process | Format-Table -Auto | Out-String | ForEach-Object { $_ -split \"`n\" } |\n\u003e\u003e   Where-Object { $_ -match 'pwsh' }\n# Good luck extracting CPU from that\n\n# After: typed objects through the entire pipeline\nPS\u003e $top = ps aux | sort -k3 -rn | head 5\nPS\u003e $top[0].ProcessName   # pwsh\nPS\u003e $top[0].CPU           # 12.4     (decimal, not a string)\nPS\u003e $top[0].PID           # 1847     (integer, not a substring)\nPS\u003e $top | Where-Object { $_.CPU -gt 5.0 } | ForEach-Object { Stop-Process $_.PID -WhatIf }\n```\n\n### 2. Pipeline bridge: objects survive grep and sort\n\n```powershell\nPS\u003e ls -la | grep '.ps1' | sort -k5 -h\n\n-rw-r--r-- 1 beagle wheel     4521 Apr  2 00:57 PsBash.psd1\n-rw-r--r-- 1 beagle wheel    89234 Apr  2 09:46 PsBash.Tests.ps1\n-rw-r--r-- 1 beagle wheel   141234 Apr  2 09:46 PsBash.psm1\n\n# grep matched the TEXT, but passed through the TYPED OBJECTS:\nPS\u003e $files = ls -la | grep '.ps1' | sort -k5 -h\nPS\u003e $files[0].GetType().Name       # PSCustomObject (LsEntry)\nPS\u003e $files.Name                    # PsBash.psd1, PsBash.Tests.ps1, PsBash.psm1\nPS\u003e $files.SizeBytes | Measure-Object -Sum | Select -Expand Sum\n234989\n```\n\n### 3. Built-in jq, awk, sed — no external binaries\n\n```powershell\nPS\u003e echo '{\"db\":\"postgres\",\"port\":5432}' | jq '.db'\n\"postgres\"\n\nPS\u003e cat app.log | grep ERROR | awk '{print $1, $3}' | sort | uniq -c | sort -rn | head 5\n      47 2024-01-15 DatabaseError\n      23 2024-01-15 TimeoutError\n      12 2024-01-15 AuthError\n\nPS\u003e find . -name '*.log' -mtime +7 | xargs rm -f    # actually works on Windows\n```\n\n## Two Modes: Module and Shell\n\nPsBash can be used as a **PowerShell module** or a **standalone shell**. They share the same 77 bash commands and typed object pipeline.\n\n### Module — bash commands inside PowerShell\n\n```powershell\nInstall-Module PsBash\nls -la | grep '.cs' | sort -k5 -h        # typed objects through the pipeline\n$procs = ps aux | sort -k3 -rn | head 5  # .PID, .CPU are real .NET types\n```\n\nBest for: scripts, VS Code terminal, CI/CD, mixing bash with PowerShell cmdlets.\n\n### Shell — standalone bash terminal on Windows\n\n```bash\n# Launch as your shell\nps-bash\n\n# Inside: bash aliases, .psbashrc, colored prompt, external tools\nll                           # alias: ls -al\ncd ~/projects \u0026\u0026 git status  # cd + external git\nclaude                       # full interactive AI session\n```\n\nBest for: Windows Terminal, AI coding agents (Claude Code, OpenCode), replacing WSL/Git Bash.\n\n→ **See the full [Shell Guide](docs/shell-guide.md)** for setup, configuration, mixing bash + PowerShell, and limitations.\n\n## Using ps-bash inside PowerShell\n\nInstall the binary cmdlet module to get `Invoke-BashEval` and `Invoke-BashSource` for transpiling and evaluating bash directly from PowerShell:\n\n```powershell\nInstall-Module PsBash.Cmdlets\n```\n\n`PsBash` is automatically pulled in as a dependency. Quickstart:\n\n```powershell\n# Transpile a bash command to PowerShell\nInvoke-BashEval 'ls -la | grep .ps1'\n\n# Source a bash script into the current PowerShell session\nInvoke-BashSource ./my-script.sh\n\n# Test if a bash command is valid syntax\nTest-BashSyntax 'echo hello | wc -l'\n```\n\n→ See the [Shell Guide](docs/shell-guide.md) for details on dynamic-env tools and advanced usage.\n\n## AI Coding Agent Setup\n\nPs-bash works as a drop-in bash replacement for AI coding agents on Windows. Agents invoke `ps-bash -c \"command\"` and it transpiles bash to PowerShell transparently.\n\n### Quick Setup for Claude Code\n\n```powershell\n# Add to $PROFILE or set before launching claude\n$env:CLAUDE_CODE_SHELL = 'C:\\Users\\you\\.local\\bin\\ps-bash.exe'\n```\n\nOr in `~/.claude/settings.json`:\n\n```json\n{\n  \"env\": {\n    \"CLAUDE_CODE_SHELL\": \"C:\\\\Users\\\\you\\\\.local\\\\bin\\\\ps-bash.exe\"\n  }\n}\n```\n\n### Quick Setup for OpenCode\n\n```powershell\n$env:SHELL = 'C:\\Users\\you\\.local\\bin\\ps-bash.exe'\nopencode\n```\n\n### Quick Setup for GitHub Copilot (VS Code)\n\nIn VS Code `settings.json`:\n\n```json\n{\n  \"terminal.integrated.profiles.windows\": {\n    \"ps-bash\": {\n      \"path\": \"C:\\\\Users\\\\you\\\\.local\\\\bin\\\\ps-bash.exe\"\n    }\n  },\n  \"terminal.integrated.defaultProfile.windows\": \"ps-bash\"\n}\n```\n\n### Supported Agents\n\n| Agent | Config Method | Setting |\n|-------|--------------|---------|\n| **Claude Code** | `CLAUDE_CODE_SHELL` env var or `settings.json` | `CLAUDE_CODE_SHELL=C:\\path\\to\\ps-bash.exe` |\n| **OpenCode** | `$SHELL` environment variable | `$env:SHELL = 'C:\\path\\to\\ps-bash.exe'` |\n| **GitHub Copilot** | VS Code terminal profile | `terminal.integrated.defaultProfile.windows` |\n| **Gemini CLI** | Not configurable (hardcoded shell) | Run inside ps-bash interactive shell |\n\nSee [docs/agent-setup.md](docs/agent-setup.md) for detailed per-agent configuration, Docker setup, and troubleshooting.\n\n## Feature Comparison\n\n| | **PsBash** | **Git Bash** | **Cygwin** | **WSL** | **Crescendo** |\n|---|---|---|---|---|---|\n| Install | `Install-Module` | Git for Windows | 50+ packages | Hyper-V/WSL2 | Per-command XML |\n| Footprint | **340 KB**, 3 files | ~300 MB (MSYS2 runtime) | ~1-4 GB | ~1-15 GB (full distro) | Module + your wrappers |\n| `rm -rf` works | Yes | Yes | Yes | Yes | If you configure it |\n| Typed objects | Always | Never (strings) | Never (strings) | Never (strings) | If configured |\n| Object pipeline | Types survive `grep \\| sort \\| head` | Strings only | Strings only | Strings only | Varies |\n| PowerShell integration | Native — objects flow into cmdlets | Separate shell | Separate shell | Separate shell | Native |\n| Cross-platform | Win/Lin/Mac | Windows only | Windows only | Windows only | Win/Lin/Mac |\n| Commands | 77 built-in | ~80 (GNU coreutils) | ~200+ (full GNU) | All of Linux | Define your own |\n| jq/awk/sed | Built-in, zero binaries | awk/sed yes, jq no | Yes (install pkg) | Yes (apt install) | Not included |\n| PATH conflicts | None (AllScope aliases) | Shadows PowerShell | Shadows PowerShell | Filesystem boundary | None |\n| Startup overhead | ~100 ms (module load) | New process per call | New process per call | ~1s (cold), ~200ms (warm) | ~100 ms |\n| AI agent shell | Yes (`ps-bash -c`) | No | No | No | No |\n| Interactive mode | Yes (aliases, prompt, external tools) | Yes (full bash) | Yes (full bash) | Yes (full Linux) | No |\n\n## 77 Commands\n\n| Category | Commands |\n|----------|----------|\n| **Listing** | `ls` `find` `stat` `tree` `du` `pwd` `basename` `dirname` `realpath` `dirs` |\n| **Files** | `cp` `mv` `rm` `mkdir` `rmdir` `touch` `ln` |\n| **Content** | `cat` `head` `tail` `less` `tac` `wc` `nl` `rev` `strings` `fold` `expand` `unexpand` `split` |\n| **Search** | `grep` `rg` |\n| **Text** | `sed` `awk` `cut` `tr` `uniq` `sort` `column` `join` `paste` `comm` `diff` |\n| **Pipeline** | `tee` `xargs` `yes` |\n| **Data** | `jq` `yq` `xan` |\n| **System** | `ps` `env` `date` `hostname` `whoami` `which` `alias` `time` `sleep` `tput` `pushd` `popd` |\n| **Shell** | `shopt` `type` `source` `command` `unset` `shift` |\n| **Output** | `echo` `printf` |\n| **Encoding** | `base64` `md5sum` `sha1sum` `sha256sum` `file` |\n| **Archive** | `gzip` `gunzip` `zcat` `tar` |\n| **Math** | `seq` `expr` |\n\nEvery command supports `--help` and tab completion for all flags.\n\n## PsBash vs Native PowerShell\n\n| Task | PsBash | Native PowerShell |\n|------|--------|-------------------|\n| List files | `ls -la` | `Get-ChildItem -Force \\| Format-List` |\n| Find by name | `find . -name '*.ps1'` | `Get-ChildItem -Recurse -Filter *.ps1` |\n| Top 5 CPU | `ps aux \\| sort -k3 -rn \\| head 5` | `Get-Process \\| Sort-Object CPU -Desc \\| Select -First 5` |\n| Count lines | `wc -l file.txt` | `(Get-Content file.txt).Count` |\n| Search files | `grep -r 'TODO' src/` | `Select-String -Path src/* -Pattern TODO -Recurse` |\n| JSON field | `cat f.json \\| jq '.name'` | `(Get-Content f.json \\| ConvertFrom-Json).name` |\n| Delete tree | `rm -rf dist/` | `Remove-Item dist/ -Recurse -Force` |\n| Disk usage | `du -sh * \\| sort -rh` | `Get-ChildItem \\| Sort Length -Desc \\| Select Name,Length` |\n\nBoth sides give you objects. PsBash just lets you type what you already know.\n\n## How It Works\n\nEvery PsBash command returns a PSCustomObject with a `.BashText` property. The terminal renders BashText (looks like real bash). Your code accesses typed properties.\n\n```\n  ls -la\n    |\n  Invoke-BashLs\n    |\n  [LsEntry] objects\n    .Name         = \"README.md\"\n    .SizeBytes    = 4521             [int]\n    .Permissions  = \"-rw-r--r--\"     [string]\n    .Owner        = \"beagle\"         [string]\n    .LastModified = 2024-04-02...    [DateTime]\n    .BashText     = \"-rw-r--r-- 1 beagle wheel  4521 Apr  2 ...\"\n```\n\nPipeline commands (`grep`, `sort`, `head`, `tail`, `tee`) match against BashText but pass through the **original typed objects**. This is the pipeline bridge — the core architectural pattern.\n\nThe standalone `ps-bash` binary adds a transpiler layer:\n\n```\nbash input → BashLexer → BashParser → PsEmitter → IpcWorker → ps-bash-host/SdkWorker → PowerShell SDK\n```\n\nThe parser tokenizes and parses bash into an AST modeled on Oils syntax.asdl. The emitter maps bash commands to `Invoke-Bash*` functions, forwarding all arguments unchanged. The runtime PowerShell module handles all flag parsing with full bash-compatible behavior.\n\n## Testing\n\n```powershell\nInvoke-Pester ./tests/PsBash.Tests.ps1\n# 857 tests: 561 Core (parser/emitter), 96 Shell (e2e), 200 Module (runtime)\n```\n\nCI runs on Windows, Linux, and macOS via GitHub Actions.\n\n## Cross-Platform\n\n| Feature | Linux/macOS | Windows |\n|---------|-------------|---------|\n| File permissions | Real POSIX (`rwxr-xr-x`) | Approximated from ACLs |\n| `ps` backend | `/proc` filesystem | .NET `System.Diagnostics.Process` |\n| `ln -s` | Works normally | Requires Developer Mode |\n| `stat` | `/usr/bin/stat` | Pure .NET implementation |\n\n## Documentation\n\n**[standardbeagle.github.io/ps-bash](https://standardbeagle.github.io/ps-bash/)** — full command reference, object type specs, pipeline cookbook, cross-platform guide.\n\n- **[Interactive Shell Guide](docs/shell-guide.md)** — running ps-bash as a shell, .psbashrc config, mixing bash and PowerShell, command routing\n- **[Agent Setup Guide](docs/agent-setup.md)** — configure Claude Code, OpenCode, Copilot, and Gemini CLI to use ps-bash\n- **[Parser Grammar](docs/specs/parser-grammar.md)** — tokens, AST nodes, grammar productions\n- **[Emitter Strategy](docs/specs/emitter-strategy.md)** — passthrough principle, pipe mappings\n- **[Runtime Functions](docs/specs/runtime-functions.md)** — BashObject model, arg-parsing patterns, adding a command\n- **[Command Reference](docs/specs/runtime-command-reference.md)** — per-command flag / arg-parsing lookup table\n- **[Migrated Binary Cmdlets](docs/specs/runtime-migrated-cmdlets.md)** — REFACTOR-2 binary-cmdlet migration history\n\n## License\n\nMIT\n\n## Contributing\n\nIssues and PRs welcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstandardbeagle%2Fps-bash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstandardbeagle%2Fps-bash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstandardbeagle%2Fps-bash/lists"}