From a bash shell inside WSL you can type `notepad.exe` and a Windows program opens, and you can pipe Linux output into it. What makes that work, and what goes wrong when you pass a Linux path such as /home/me/report.txt to a Windows program?
answer
- the kernel routes it, not bash
- registered handler for a foreign format
- stdio is wired across the boundary
- Windows cannot read a Linux path
- one command translates both ways
basics
~20 sWSL registers Windows executables with the Linux kernel's binfmt_misc mechanism, so exec'ing a .exe hands it to an interop service that starts it on the Windows side with stdio piped back. Windows programs cannot understand Linux paths, so convert them with wslpath.
solid answer
~50 sWSL registers a `binfmt_misc` handler for Windows PE executables inside the distribution. When you exec `notepad.exe`, the Linux kernel routes it to WSL's interop handler, which asks the Windows side to create the process and wires its standard input, output and error back to your shell — which is why `ls | clip.exe` works. Those binaries are found on your `PATH` because WSL appends the Windows `PATH`, translated to `/mnt/...` entries; that behaviour is `appendWindowsPath` in the `[interop]` section of `/etc/wsl.conf`. The catch is paths: the Windows process is a genuine Windows process and resolves `/home/me/report.txt` against the current drive, so it fails or creates something unexpected. Convert with `wslpath -w /home/me/report.txt` before passing it, and `wslpath -u` in the other direction. Under WSL2 the Linux path becomes a `\\wsl$` UNC path, which some Windows tools handle poorly.
code
bash · 8 lines# Launch a Windows tool on a Linux file, with the path translated
notepad.exe "$(wslpath -w ./report.txt)"
# Pipe Linux output into a Windows program
ls -l | clip.exe
# Convert a Windows path back to a Linux one
wslpath -u 'C:\Users\me\Downloads'go deeper
Know that you can run Windows programs from a WSL shell and pipe data through them, and that a Linux path must be converted with wslpath before a Windows program will understand it.
Explain the mechanism: a binfmt_misc registration for Windows executables plus an interop service that creates the Windows process and wires stdio back, and name the /etc/wsl.conf settings that control interop and PATH appending.
Point out the operational consequences: PATH pollution and shadowed interpreters, UNC working directories that older tools reject, cross-boundary slowness when Windows tools work on Linux files, and when to disable interop outright.
Decide whether interop belongs in the standard developer image at all — a build environment that silently resolves commands to Windows binaries is not reproducible, which argues for disabling it and pushing real builds onto Linux hosts or containers.
## The mechanism: binfmt_misc plus an interop service Linux has a general facility called `binfmt_misc` that lets user space register handlers for file formats the kernel does not natively execute, matched by magic bytes or filename extension. WSL uses it: inside the distribution there is a registration for Windows PE/COFF binaries. When you `exec` a `.exe`, the kernel recognises the format and hands it to WSL's interop handler instead of trying to load it as an ELF. The handler does not run Windows code inside Linux. It asks the Windows side to create a real Windows process, and connects that process's standard input, output and error back to the file descriptors of the Linux process that launched it. That plumbing is why the two worlds compose in a pipeline: ```bash ls -l | clip.exe # Linux output into the Windows clipboard cmd.exe /c ver | tr -d '\r' # Windows output into a Linux filter ``` Interop exists in both WSL1 and WSL2 — it is not a property of the VM. ## Why the .exe is on your PATH By default WSL appends the Windows `PATH` to the Linux `PATH`, with each entry rewritten to its `/mnt/...` form. That is why `notepad.exe`, `code` and other Windows tools resolve without a full path. It has costs. `PATH` becomes long, so tab completion and command lookup slow down, and Windows entries can shadow or be shadowed by Linux ones — the Windows Store `python.exe` app-execution alias colliding with a Linux `python` is the classic case. Both behaviours are configurable per distribution in `/etc/wsl.conf`: ```ini [interop] enabled = true appendWindowsPath = false ``` Setting `enabled = false` disables launching Windows processes entirely, which is what you want in a distribution used as a build or CI environment where surprising `PATH` resolution is a hazard. Changes take effect after the distribution restarts. ## The path problem The process you launched is an ordinary Windows process with a Windows view of the filesystem. It has no idea what `/home/me/report.txt` means; Windows resolves a leading `\` or `/` against the current drive, so the tool either errors out or silently touches the wrong location. The translation tool ships with WSL: ```bash wslpath -w /home/me/report.txt # Linux path -> Windows path wslpath -u 'C:\Users\me\report.txt' # Windows path -> Linux path notepad.exe "$(wslpath -w ./report.txt)" ``` For a file under `/mnt/c`, `wslpath -w` produces an ordinary drive path. For a file in the Linux filesystem under WSL2, it produces a **UNC path** of the form `\\wsl$\<distro>\home\me\report.txt` (`\\wsl.localhost\...` on current versions). Modern GUI applications generally cope; some older console tools and `cmd.exe` do not accept a UNC path as a working directory and warn about it. Remember too that reaching Linux files that way goes back over the 9P boundary, so a Windows tool crunching many files on the Linux side will be slow — the mirror image of the usual `/mnt/c` performance advice. ## The other direction From PowerShell or `cmd.exe` you invoke Linux the same way: `wsl <command>` runs it in the default distribution, `wsl -d <distro> -- <command>` picks one, and `wsl --cd <dir>` sets the working directory. Explorer opens `\\wsl.localhost\<distro>` to browse Linux files, and from Linux `explorer.exe .` opens the current directory in Explorer. ## Two more practical wrinkles - **Environment variables** do not flow across automatically. `WSLENV` is the documented mechanism for sharing selected variables between Windows and WSL, including flags for path translation. - **Line endings.** Files written by Windows tools carry CRLF, so a script saved that way and run from Linux fails with a confusing interpreter error. Configure your editor, or your Git checkout behaviour, accordingly. ## What the interviewer is checking At this level, that you know interop is a real kernel-level registration rather than magic, that you reach for `wslpath` instead of hand-editing paths, and that you know the setting which turns the `PATH` appending off when it causes trouble.
- Why would you deliberately set appendWindowsPath to false?To stop the Windows `PATH` from leaking into the Linux shell. It shortens a very long `PATH` (speeding up command lookup and tab completion) and removes name collisions, such as a Windows app-execution alias shadowing the Linux interpreter you meant to run. It is a sensible default for a distribution used as a build environment, where surprising resolution causes hard-to-explain failures.
- What does wslpath -w return for a file inside the Linux filesystem under WSL2?A UNC path of the form `\\wsl$\<distro>\...` (spelled `\\wsl.localhost\...` on current versions), because the Linux filesystem is not on a Windows drive letter. Most GUI applications handle it, but some console tools and `cmd.exe` refuse a UNC working directory, and access goes back across the 9P boundary, so bulk file work through it is slow.
- How do you run a Linux command from a PowerShell prompt?With `wsl <command>`, which runs it in the default distribution, or `wsl -d <distro> -- <command>` to target a specific one; `wsl --cd <dir>` sets the working directory for that invocation. Output comes back to the PowerShell pipeline as text, so it composes with Windows tooling in the same way interop composes in the other direction.
saying these in an interview costs you the question
- Thinking bash special-cases .exe filenames itself
- Passing Linux paths straight to Windows programs
- Believing interop only exists in WSL2
- Assuming environment variables cross automatically
- Expecting a Windows program to see / as the Linux root