π οΈ Unix Executable Emulators for Windows
May 1, 2026 Β· View on GitHub
16 standalone UNIX utilities written in V β bridging the gap between Windows and UNIX shell environments for AI agents and developer tools.
π§π· Leia em portuguΓͺs
Table of Contents
- Why This Exists
- Quick Start
- Tool Reference
- Argument Policy
- Testing
- Architecture
- Building
- RTK on Windows β Agent Prompt Template
Why This Exists
Windows lacks native equivalents of standard UNIX commands (ls, grep, find, etc.). While PowerShell provides aliases, they are incompatible with external programs that expect real executables on PATH.
Built for rtk
The core motivation is token economy for AI agents. When an LLM calls PowerShell cmdlets like Select-String or Get-ChildItem, the output is verbose, object-formatted, and often hundreds of lines. This wastes thousands of tokens per call β tokens you pay for.
These executables produce dense, UNIX-style plain-text output consumable in a single glance. Paired with rtk (AI proxy), they let agents execute CLI operations with short pipelines like:
rtk grep -n "pattern" path | rtk head -n 80
rtk findd ./src -name "*.ts" | xargs grep "TODO" | rtk head -n 200
To get the most out of this setup, use the agent system prompt provided in AGENTS_SUGGESTION_FOR_RTK.md. It enforces mandatory rtk wrappers, forbids verbose PowerShell cmdlets, and auto-excludes binary/dependency directories β all designed to minimize token waste.
The binaries:
- Work as real executables β callable from any shell, script, or external tool (e.g.,
rtk, AI agents like Codex/Gemini) - Return POSIX exit codes β
0for success,1for no match/error,2for usage errors - Support common GNU/UNIX flags β progressively implementing the most-used flags
- Handle Windows paths β backslash/forward-slash normalization,
PATHEXTsupport - Auto-exclude noisy directories β
node_modules,.git,vendor, etc. are skipped by default in recursive scans - Auto-detect literal patterns β grep bypasses the regex engine when the pattern has no meta-characters, cutting RAM from GBs to MBs
Quick Start
Prerequisites
- V compiler installed and on PATH
Build All
cd executables
.\build.bat
# or
powershell -File .\build.ps1
Build Single Tool
cd executables\exe_ls
.\build.bat
Binaries are compiled to the project root (two levels above each exe_<tool> directory). Place them in a directory on your PATH.
First Usage
ls -la .
grep -rn "TODO" ./src --include="*.v"
find . -iname "*.txt" -type f
cat -n file.txt | head -n 20
sort data.csv | uniq -c
Tool Reference
File Listing & Inspection
ls β List directory contents
ls [OPTIONS] [FILE...]
| Flag | Description |
|---|---|
-a, --all | Show hidden files (starting with .) |
-A, --almost-all | Like -a but exclude . and .. |
-l, --long | Long listing format with permissions, size, date |
-h, --human-readable | Human-readable sizes (1K, 234M, 2G) with -l |
--si | Like -h but use powers of 1000 |
-r, --reverse | Reverse sort order |
-R, --recursive | List subdirectories recursively |
-1, --one-line | One file per line |
-m, --commas | Comma-separated list |
-S | Sort by file size (largest first) |
-t | Sort by modification time (newest first) |
-v | Natural sort of version numbers (file2 before file10) |
-X | Sort alphabetically by extension |
-U | Do not sort (directory order) |
-F, --classify | Append indicator (`*/=>@ |
-p, --slash | Append / to directories |
--group-directories-first | Group directories before files |
-i, --inode | Print inode number |
-s, --size | Print allocated size in blocks |
-n, --numeric-uid-gid | Numeric user/group IDs |
-g, --no-owner | Like -l but hide owner |
-G, --no-group | Hide group in long listing |
-o | Like -l but hide group |
-d, --directory | List directories themselves, not contents |
-Q, --quote-name | Enclose names in double quotes |
-b, --escape | C-style escapes for non-graphic characters |
--color=WHEN | Colorize output (always, auto, never) |
--time-style=STYLE | Time format (full-iso, long-iso, iso, locale) |
--full-time | Like -l --time-style=full-iso |
-u | Sort/show access time |
-c | Sort/show status change time |
pwd β Print working directory
pwd [OPTIONS]
| Flag | Description |
|---|---|
-L | Use PWD from environment (default) |
-P | Resolve all symlinks (stub) |
Outputs forward-slash paths for UNIX compatibility.
which β Locate a command
which [OPTIONS] COMMAND...
| Flag | Description |
|---|---|
-a, --all | Print all matching pathnames |
Searches PATH directories and respects PATHEXT on Windows.
File Content
cat β Concatenate and display files
cat [OPTIONS] [FILE...]
| Flag | Description |
|---|---|
-n, --number | Number all output lines |
-b, --number-nonblank | Number non-empty lines only (overrides -n) |
-s, --squeeze-blank | Suppress repeated empty lines |
-E, --show-ends | Display $ at end of each line |
-T, --show-tabs | Display TAB as ^I |
-A, --show-all | Equivalent to -vET |
Reads from stdin when no file is specified or file is -.
head β Output first part of files
head [OPTIONS] [FILE...]
| Flag | Description |
|---|---|
-n K, --lines=K | Print first K lines (default: 10) |
-c K, --bytes=K | Print first K bytes |
-v, --verbose | Always print file name headers |
-q, --quiet | Never print file name headers |
tail β Output last part of files
tail [OPTIONS] [FILE...]
| Flag | Description |
|---|---|
-n K, --lines=K | Output last K lines (default: 10) |
-f, --follow | Output appended data as file grows |
-s N, --sleep-interval=N | Sleep N seconds between follow iterations |
-v, --verbose | Always print file name headers |
-q, --quiet | Never print file name headers |
Performance: Uses seek-from-end approach β handles multi-GB files without loading them into memory.
Search & Filter
grep β Search for patterns in files
grep [OPTIONS] PATTERN [FILE...]
| Flag | Description |
|---|---|
-i, --ignore-case | Case-insensitive matching |
-v, --invert-match | Select non-matching lines |
-n, --line-number | Print line numbers |
-c, --count | Print only match count per file |
-l, --files-with-matches | Print only filenames with matches |
-L, --files-without-matches | Print only filenames without matches |
-r, -R, --recursive | Search directories recursively |
-w, --word-regexp | Match whole words only |
-x, --line-regexp | Match whole lines only |
-F, --fixed-strings | Treat pattern as literal string |
-o, --only-matching | Show only the matched part of lines |
-H, --with-filename | Print filename with output |
-h, --no-filename | Suppress filename prefix |
-A N, --after-context=N | Print N lines after each match |
-B N, --before-context=N | Print N lines before each match |
-C N, --context=N | Print N lines of context (before + after) |
-m N, --max-count=N | Stop after N matches per file |
-q, --quiet | Suppress all output |
-s, --silent | Suppress error messages |
--color=WHEN | Colorize matches (always, auto, never) |
--exclude=GLOB | Skip files matching GLOB |
--exclude-dir=DIR | Skip directories matching DIR |
--include=GLOB | Search only files matching GLOB |
Performance: Auto-detects literal patterns to bypass the regex engine, circular buffer for context lines (O(1) vs O(n) for before-context), auto-excludes
node_modules/.git/vendor/etc in recursive scans, iterative BFS-based directory traversal.
find β Search for files in directory hierarchy
find [PATH...] [OPTIONS]
| Flag | Description |
|---|---|
-name PATTERN | Match filename (case-sensitive glob) |
-iname PATTERN | Match filename (case-insensitive glob) |
-type TYPE | Filter by type (f = file, d = directory) |
-empty | Match empty files/directories |
-maxdepth N | Descend at most N levels |
-delete | Delete matched files |
-o, -or | OR operator between filter groups |
Supports combining multiple filters with -o (OR logic). Glob patterns use * and ?.
Performance: Regex patterns are pre-compiled once at startup, not per-file.
sort β Sort lines of text files
sort [OPTIONS] [FILE...]
| Flag | Description |
|---|---|
-r, --reverse | Reverse sort order |
-n, --numeric-sort | Compare by numerical value |
-u, --unique | Output only unique lines |
uniq β Filter adjacent duplicate lines
uniq [OPTIONS] [INPUT [OUTPUT]]
| Flag | Description |
|---|---|
-c, --count | Prefix lines by occurrence count |
-d, --repeated | Only print duplicate lines |
-u, --unique | Only print unique lines |
-i, --ignore-case | Case-insensitive comparison |
File Operations
cp β Copy files and directories
cp [OPTIONS] SOURCE... DEST
| Flag | Description |
|---|---|
-r, -R, --recursive | Copy directories recursively |
-f, --force | Force overwrite |
-i, --interactive | Prompt before overwrite |
-n, --no-clobber | Do not overwrite existing files |
-v, --verbose | Explain what is being done |
mv β Move/rename files
mv [OPTIONS] SOURCE... DEST
| Flag | Description |
|---|---|
-f, --force | Do not prompt before overwriting |
-i, --interactive | Prompt before overwrite |
-n, --no-clobber | Do not overwrite existing files |
-v, --verbose | Explain what is being done |
rm β Remove files and directories
rm [OPTIONS] FILE...
| Flag | Description |
|---|---|
-r, -R, --recursive | Remove directories recursively |
-f, --force | Ignore nonexistent files, never prompt |
-i, --interactive | Prompt before every removal |
-v, --verbose | Explain what is being done |
-d, --dir | Remove empty directories |
mkdir β Create directories
mkdir [OPTIONS] DIRECTORY...
| Flag | Description |
|---|---|
-p, --parents | Create parent directories as needed |
-v, --verbose | Print message for each created directory |
touch β Update file timestamps
touch [OPTIONS] FILE...
| Flag | Description |
|---|---|
-c, --no-create | Do not create any files |
-a | Change only the access time |
-m | Change only the modification time |
Utilities
xargs β Build and execute commands from stdin
xargs [OPTIONS] [COMMAND [ARGS...]]
| Flag | Description |
|---|---|
-0, --null | Input items separated by NUL (for find -print0) |
-I REPLACE | Replace REPLACE in args with each input item |
-n MAX | Use at most MAX arguments per command |
-t, --verbose | Print commands before execution |
-r, --no-run-if-empty | Don't run command if stdin is empty |
Examples:
find . -name "*.txt" | xargs grep "TODO"
find . -print0 | xargs -0 wc -l
echo file1 file2 | xargs -I {} cp {} /backup/
ls *.log | xargs -n 2 echo "Batch:"
Argument Policy
For any flag that is not yet implemented, the tools return a standardized error message:
TODO (UNIX WINDOWS): THIS ARGUMENT HAS NOT YET BEEN IMPLEMENTED.
USE AN ALTERNATIVE METHOD, AS THE "ls" COMMAND DOES NOT YET HAVE THIS ARGUMENT "-la".
This message is designed for AI agents to understand and use alternative approaches.
Testing
Each tool has integration tests in its tests/ directory:
# Run tests for a specific tool
cd executables\exe_grep
v test tests/
# Run all tests
Get-ChildItem -Directory exe_* | ForEach-Object {
Write-Host "Testing $($_.Name)..."
Push-Location $_.FullName
v test tests/
Pop-Location
}
Tests use os.execute() to run the compiled binary and verify exit codes and output. New features and optimizations require new tests β see AGENTS.md for the full testing policy.
Architecture
executables/
βββ AGENTS.MD # Agent-facing documentation & testing policy
βββ README.md # This file
βββ README.pt-br.md # Brazilian Portuguese version
βββ build.ps1 # Build all tools
βββ build.bat # Wrapper for build.ps1
βββ exe_ls/ # Each tool in its own directory
β βββ main.v # Entry point & argument parsing
β βββ lister.v # Core logic (directory listing)
β βββ filedata.v # Data structures
β βββ options.v # Options struct
β βββ utils.v # Utility functions
β βββ build.bat # Individual build script
β βββ tests/
β βββ ls_test.v # Integration tests
βββ exe_grep/
β βββ main.v
β βββ matcher.v # Regex/fixed-string matching engine
β βββ processor.v # File processing & output
β βββ filters.v # --exclude/--include handling
β βββ options.v
β βββ tests/
β βββ grep_test.v
β βββ context_test.v
β βββ exclude_test.v
β βββ literal_test.v
β βββ autoexclude_test.v
βββ ... # 14 more tools following the same pattern
Conventions
- Directory naming:
exe_<command>(e.g.,exe_ls,exe_grep) - Build output: Each
build.batcompiles to../../<command>.exe(thebin/root) - Build flags: All builds use
-prodfor optimized release binaries - Module: All files use
module main - Options: Parsed with V's
flagmodule, stored in anOptionsstruct
Building
Single Tool
cd executables\exe_ls
v -prod -o "..\..\ls.exe" .
All Tools
cd executables
.\build.ps1
Development (fast, no optimizations)
cd executables\exe_ls
v -o "..\..\ls.exe" .
RTK on Windows β Agent Prompt Template
To get the most out of these tools with rtk, use the agent system prompt provided in AGENTS_SUGGESTION_FOR_RTK.md. It enforces:
- MANDATORY use of
rtkwrappers for CLI operations on Windows - FORBIDDEN use of native PowerShell cmdlets (
Select-String,Get-Content,Get-ChildItem) for file/text operations - Short UNIX-style pipelines with
rtk grep ... | rtk head ... - Targeted paths/extensions over broad recursive scans from
. findd | xargs grepto narrow by directory and file type before runninggrep- Auto-exclusion of binary files,
node_modules,.git,build/,dist/, etc. - Auto-exclusion of binary extensions:
*.exe,*.dll,*.sqlite,*.png,*.pdf,*.zip, etc.
See the file for the full ready-to-copy prompt and examples.
Why this matters: PowerShell cmdlets produce verbose, object-formatted output that wastes thousands of AI tokens per call. These UNIX-style tools output dense plain text β a single
rtk grep ... | rtk head -n 80can replace a 200-line PowerShell output with 3-5 lines the LLM can consume instantly.
License
Internal tooling β part of the rtk ecosystem.