Developer Tools

Coreutils for Windows: How to Get Native `ls` and `grep`, and the Catch With Your Scripts

Microsoft's Coreutils for Windows brings native Linux commands like ls, grep, and cp without WSL. How to install it and the PowerShell alias catch.

Coreutils for Windows: How to Get Native `ls` and `grep`, and the Catch With Your Scripts editorial image

If you move between a Mac or a Linux box and a Windows machine all day, you know the small daily friction: you type ls -la out of habit, and Windows either hands you PowerShell's own version of ls with different flags, or nothing useful at all. The short answer to the news below: Microsoft now ships the real Linux-style commands as native Windows programs, it is genuinely worth installing if you live in a terminal, and the catch is that it changes which program answers when you type ls, cp, or rm. For years the fixes were the same three: install Git Bash, lean on WSL, or retrain your fingers to speak PowerShell. At Build 2026 on June 2, Microsoft added a fourth option that is more direct than any of them, and it is worth understanding before you install it, because it changes how some commands you already type will behave.

The release is called Coreutils for Windows. It puts a large set of Linux-style command-line tools on Windows as real, native executables, with no virtual machine and no WSL layer underneath. That is genuinely useful. It also collides with commands Windows already ships, and that collision is the part the announcement makes easy to overlook.

What Microsoft actually shipped

Coreutils for Windows is generally available now, distributed as a Microsoft-maintained package on GitHub under the MIT license. Microsoft did not write the underlying tools from scratch. The package is built on uutils, an open-source reimplementation of the GNU coreutils written in Rust, bundled together with findutils and a GNU-compatible grep into a single program.

The packaging detail matters more than it sounds. Instead of shipping a separate .exe for every command, Microsoft ships one binary, coreutils.exe, that lives in C:\Program Files\coreutils\. During install it creates NTFS hardlinks named ls.exe, cp.exe, cat.exe, rm.exe, and so on, all pointing back at that one file. When you run ls, the binary checks what name it was invoked under and behaves like that command. It is the same multi-call trick BusyBox has used on Linux for years, and it keeps the install small.

Early coverage from outlets including BleepingComputer and Phoronix counted more than 75 utilities in the package, the everyday set you would expect: cat, cp, mv, rm, ls, find, grep, sort, echo, pwd, tee, sleep, hostname, uptime, and many more. The point Microsoft keeps making is portability: the pipelines and one-liners you have built up over years on Linux, macOS, or inside WSL are meant to run largely the same way directly on Windows, within the platform limits covered further down. For scripting that crosses platforms, that convenience is real.

How to install it

The simplest path is Windows Package Manager. Open a terminal and run:

winget install Microsoft.Coreutils

If you would rather not use winget, the project's GitHub releases page has the packaged download directly. One requirement to check first: the package targets a current shell, and PowerShell 7.4 or newer is expected. If you are still on Windows PowerShell 5.1 — the version that ships in the box — plan to install the newer PowerShell alongside it before you rely on these tools.

After installation the Coreutils commands become available on your PATH, which is exactly where the interesting behavior starts.

The catch: PowerShell aliases and PATH order

Here is the thing to understand before you type your first command: Windows already has things called ls, cp, mv, and rm. In PowerShell those are built-in aliases — ls is really Get-ChildItem, cp is Copy-Item, mv is Move-Item, rm is Remove-Item. Once Coreutils is on your PATH, you have two different ls commands fighting for the same two letters, and they do not take the same flags or print the same output.

Which one wins follows a firm rule, just not an obvious one. In PowerShell, the built-in alias takes priority over an executable on the PATH, so typing ls in a PowerShell window still gives you Get-ChildItem, not the new ls.exe. To get the Coreutils version you generally have to be explicit and call ls.exe. In cmd.exe, or in a script that shells out to the executable directly, PATH order decides it instead. The same ls can therefore mean two different programs depending on where you type it, which is precisely the kind of ambiguity that turns a working script into a confusing one.

When you are not sure which one you are getting, three quick checks settle it:

Get-Command ls       # what PowerShell actually resolves 'ls' to
where.exe ls         # every 'ls' on your PATH, in priority order
ls.exe --version     # confirm the Coreutils binary is reachable

Microsoft clearly anticipated this. The project's own documentation flags the commands that collide with built-in Windows or PowerShell equivalents, and a handful of utilities — dir, expand, more, paste, and timeout among them — are deliberately not shipped at all, because the name clash with existing Windows commands was judged too risky. That restraint is a good sign. It also tells you the conflict is real enough that the maintainers chose to drop commands rather than break your shell.

The real risk here is ambiguity rather than reliability. The documented trouble is not knowing which ls a given shell or script will resolve. Picture a developer who installs Coreutils, writes a build script that calls ls and rm expecting Linux flags, and watches it pass on their machine — then a teammate runs the same script in a PowerShell session where the aliases win, and it quietly does something else. So if you write a script that assumes ls or rm means the Coreutils version, call the .exe form explicitly, or set your PATH and aliases deliberately, rather than trusting that "ls is ls now." This is the single most likely thing to bite you, and it is worth deciding your convention up front.

What it deliberately does not do

Coreutils for Windows aims at the portable text-processing core, and the gaps are honest ones. A long list of POSIX-only commands is intentionally excluded because the POSIX semantics behind them — user IDs, permission bits, signals, and device files — do not map cleanly onto Windows: chmod, chown, chgrp, id, whoami, kill, dd, tty, stty, and similar tools are not in the package. Windows models permissions, processes, and devices differently, so a faithful version of each would be impossible anyway.

That difference shows up in a few specifics worth knowing:

  • File permissions are Windows ACLs, not POSIX permission bits, so the chmod mental model does not carry over.
  • There are no POSIX signals beyond Ctrl+C, so process control scripts that rely on kill -9 and friends will not translate.
  • Redirect to NUL, not /dev/null, when you want to discard output.
  • Creating symbolic links still needs Developer Mode enabled or an elevated prompt, the same as the rest of Windows.

Each of these reflects a genuine difference between the two operating systems rather than an unfinished feature. The project is upfront that it covers the portable, text-processing core of coreutils and leaves the system-level commands that assume a Unix kernel to WSL.

Coreutils, WSL, or Git Bash: which one for what

If you already run a Unix-style environment on Windows, the fair question is whether you need this at all. The honest answer is that they solve overlapping but different problems, and many developers will keep more than one.

ToolWhat it really isBest for
Coreutils for WindowsNative Windows .exe versions of core text/file commandsAdding familiar commands and pipelines to your existing Windows scripts and terminal without a Linux layer
WSLA real Linux kernel and distro running on WindowsRunning actual Linux software, package managers, services, and full Bash environments
Git BashA bundled MSYS2/MinGW Unix-like shellA quick Bash shell and Unix tools that come along with a Git install

The distinction that matters: Coreutils gives you Linux *commands* as Windows programs, working on Windows paths and Windows files directly. WSL gives you Linux *itself*, with its own filesystem, where crossing back to your Windows files carries a performance cost. If your goal is "let my PowerShell or batch scripts use grep and sort cleanly," Coreutils is the lighter fit. If your goal is "run the Linux toolchain my project actually targets," WSL is still the answer, and this release does not replace it.

Who should install it, and who can skip it

Install it if you regularly write or run scripts on Windows and you want the standard text-processing toolkit — grep, sort, cat, find — available as native commands without spinning up WSL. It is also a sensible default for anyone whose muscle memory is Unix and who works in a plain terminal more than in PowerShell idioms. The footprint is small and the license is permissive.

The case for skipping it is narrower but real. If your Unix work already lives in WSL and you rarely touch the Windows side of the filesystem, a second set of ls and rm definitions on your PATH buys you confusion more than convenience. PowerShell-first scripters face a different trade: you may not want Get-ChildItem and ls.exe competing in the same muscle memory when learning the PowerShell verbs you already have would do the job.

Whichever camp you are in, settle one thing before you build anything on top of it: when your scripts say ls, cp, or rm, verify exactly which program is going to answer — the PowerShell alias, the Coreutils executable, or whatever your PATH happens to resolve that day. Decide that explicitly and Coreutils is a clean addition. Leave it to chance and you have signed up for a category of bug that only appears on someone else's machine.

If you are setting up a Windows terminal for development anyway, it pairs naturally with the rest of the modern CLI stack — see our guide to installing and choosing the major terminal AI coding agents, and, if you want a local model in that same terminal, the beginner setup for running AI locally with Ollama.

Frequently asked questions

Do I need WSL or a virtual machine to use Coreutils for Windows? No. The commands run as native Windows executables. WSL solves a different problem — running a full Linux environment — and this package works without it.

Will ls automatically become the Linux version after I install it? Not in PowerShell. PowerShell's built-in ls alias (Get-ChildItem) keeps priority, so to run the Coreutils version you typically call ls.exe explicitly. In cmd.exe and in scripts, PATH order decides which one runs.

Why are chmod and chown missing? They rely on POSIX permission concepts that Windows does not use; Windows handles permissions through ACLs instead. Microsoft intentionally left out the POSIX-only commands rather than ship versions that could not behave correctly.

Source links