This document provides comprehensive information about wsl-utils configuration, advanced usage, environment variables, and troubleshooting.
Core System Variables:
WSL_INTEROP- WSL interop socket path (default:/run/WSL/1_interop)
Windows Environment Variables:
WIN_USERPROFILE- Windows user profile path (e.g.,/mnt/c/Users/username)WIN_WINDIR- Windows directory path (e.g.,/mnt/c/Windows)WIN_PROGRAMFILES- Program Files directory (e.g.,/mnt/c/Program Files)WIN_PROGRAMFILES_X86- Program Files (x86) directoryWIN_LOCALAPPDATA- User's Local AppData directoryWIN_APPDATA- User's Roaming AppData directoryWIN_ENV[]- Associative array containing Windows environment variables
- The
WIN_ENV[]associative array is only available in the main shell session and is not passed to subshells or scripts - Logging is opt-in and must be enabled with
WSLUTIL_DEBUG=1environment variable
wsl-utils supports user-specific configuration files that override system defaults. This allows customization without modifying the installed files.
Configuration File Locations:
- Factory Configuration: Resolved from the command location:
${PREFIX}/share/wslutil/config/formake install, orconfig/in a checkout. - User Configuration:
${XDG_CONFIG_HOME:-$HOME/.config}/wslutil/
Supported Configuration Files:
wslutil.yml- Windows executable configuration forwslutil setup exesandwin-run
A single wslutil.yml file drives both PATH symlinks (wslutil setup exes) and runtime path/options resolution (win-run). Factory and user configs are merged by name: factory entries are loaded first, then user entries replace whole entries for matching keys.
Locations:
- Factory:
${PREFIX}/share/wslutil/config/wslutil.yml(orconfig/wslutil.ymlin a checkout) - User:
${XDG_CONFIG_HOME:-$HOME/.config}/wslutil/wslutil.yml(delta overrides only)
Schema:
exes:
<name>:
mode: direct | shim | none # required
path: <string> # optional; supports ${WIN_*} expansion
options: <string> | null # optional; prepended by win-run onlymode |
setup exes (PATH link) |
Runtime (win-run) |
|---|---|---|
direct |
Symlink $SHIMDIR/<name> → Windows exe |
Not used (invoked directly) |
shim |
Symlink $SHIMDIR/<name> → win-run |
Path convert + UTF-8; uses path / options if set |
none |
No link; removes existing $SHIMDIR/<name> if present |
win-run <name> only; prefers path when set |
When path is omitted, setup exes discovers the Windows executable via PATH cache / Get-Command; win-run uses the bare command name.
User override example (~/.config/wslutil/wslutil.yml):
exes:
notepad++.exe:
mode: shim
path: ${WIN_PROGRAMFILES}/Notepad++/notepad++.exe
mytool.exe:
mode: none
path: ${WIN_USERPROFILE}/tools/mytool.exe
options: "--quiet"
# Disable a factory PATH link without editing factory config:
cmd.exe:
mode: noneCustom config file (-c / --config): loads that file only — no factory+user merge.
Migration from old schemas:
| Old | New |
|---|---|
winexe: [cmd.exe] |
exes.cmd.exe: { mode: direct } |
winexe: ["${…}/brave.exe"] |
exes.brave.exe: { mode: direct, path: "${…}/brave.exe" } |
winrun: [notepad.exe] |
exes.notepad.exe: { mode: shim } |
aliases.foo.path / options in win-run.yml |
exes.foo: { mode: none, path, options } (or shim/direct if a PATH link is desired) |
Old winexe / winrun / aliases keys and win-run.yml are no longer read. If ~/.config/wslutil/win-run.yml still exists, win-run and setup exes warn that entries should be moved into wslutil.yml.
Usage examples:
# Create/update PATH symlinks from merged config
wslutil setup exes
# Use a single config file (no merge)
wslutil setup exes -c ~/.config/wslutil/wslutil.yml
# win-run resolves path/options from the same merged config
win-run brave.exe https://example.com
win-run -c project.yml custom-tool.exeThe wslpath-drive utility extends standard wslpath functionality with support for Windows drive substitution:
# Standard conversion
wslpath-drive -w /home/user/file.txt
# Output: \\wsl.localhost\distro\home\user\file.txt
# With drive substitution (if Z: maps to \\wsl.localhost\distro)
wslpath-drive -W /home/user/file.txt
# Output: Z:\home\user\file.txt
# Forward slash version
wslpath-drive -M /mnt/c/projects
# Output: Z:/home/user/file.txt (if substituted)Pattern 1: Direct Command Execution
# Execute Windows commands with automatic path conversion
win-run notepad.exe /home/user/file.txt
win-run powershell.exe -Command "Get-Process"Pattern 2: Pipeline Integration
# Process Windows command output
win-run cmd.exe /c dir | grep ".txt"
win-run powershell.exe -Command "Get-Service" | grep "Running"Pattern 3: Clipboard Workflows
# Copy-paste workflows
ls -la | win-copy # Copy to Windows clipboard
win-paste | grep "important" # Search clipboard content
win-paste > restored.txt # Save clipboard to filePattern 4: WSL System Monitoring
# Monitor WSL distribution uptime (not VM uptime)
wslutil uptime # Standard uptime format
wslutil uptime --pretty # Human-readable format
wslutil uptime --since # Show WSL distro start timeAdding Custom Subcommands:
Create executable scripts named wslutil-<name> in your PATH:
#!/bin/bash
# ~/.local/bin/wslutil-mycommand
echo "This is my custom wslutil command"Usage: wslutil mycommand
Custom Windows Integration:
Add entries under exes in ~/.config/wslutil/wslutil.yml:
exes:
myapp.exe:
mode: none
path: ${WIN_PROGRAMFILES}/MyApp/bin/myapp.exe
options: "--default-config"Environment Variables Not Set
# Check if environment is loaded
echo $WIN_USERPROFILE
# Manually load if needed
eval "$(wslutil shellenv)"WSL Interop Issues
# Check WSL interop status
wslutil doctor
# Verify interop socket
ls -la $WSL_INTEROPWSL Distribution Monitoring
# Check WSL distribution uptime (different from system uptime)
wslutil uptime # Shows WSL distro uptime, not VM
uptime # Shows underlying system/VM uptime
# Useful for troubleshooting WSL restarts vs system reboots
wslutil uptime --since # When did WSL distro last start?Path Conversion Problems
# Test path conversion
wslpath-drive -w /home/user/test.txt
# Check for drive substitution
win-run subst.exeEncoding Issues with Windows Output
# Use win-run for automatic encoding handling
win-run cmd.exe /c dir
# Manual encoding conversion (advanced)
powershell.exe -Command "Get-Process" | win-utf8Enable debug logging:
export WSLUTIL_DEBUG=1
win-run notepad.exe /tmp/test.txt
# Check logs in ~/.local/state/wslutil/win-run.logOptimizing Windows Command Execution:
- Use
win-run --rawfor binary output to skip encoding conversion - Use
win-run --plainto skip automatic path conversion when not needed - Cache frequently used Windows executable paths in
wslutil.ymlexesentries
This project includes comprehensive tests using the Bats (Bash Automated Testing System) framework.
Prerequisites:
# Install bats-core (example for Ubuntu/Debian)
sudo apt-get install bats
# Or install via npm
npm install -g batsExecute Tests:
# Run all tests
make test
# Run specific test file
bats test/wslutil-setup.bats
# Verbose output
bats --verbose test/test/- Test files (*.bats)test/fixtures/- Test data and configuration filestest/helpers/- Common test utilities
Test Categories:
- Unit tests for individual script functions
- Integration tests for command workflows
- Configuration validation tests
- Cross-platform compatibility tests
WSL1:
- Direct Windows filesystem access via
/mnt/c/ - No WSLg support (manual clipboard handling)
WSL2:
- Network-based Windows integration
- WSLg support for native clipboard operations
- Enhanced security model
Windows 10:
- Basic WSL interop support
- Manual PATH management for Windows executables
Windows 11:
- Enhanced WSL integration
- Improved performance for cross-system operations
- Better Unicode support
- Fork the repository
- Clone your fork:
git clone <your-fork-url> - Create a feature branch:
git checkout -b feature-name - Make changes and add tests
- Run tests:
make test - Commit with conventional commit format
- Submit a pull request
- Use
shellcheckfor shell script linting - Follow existing code formatting patterns
- Add documentation for new features
- Include tests for new functionality
This project uses git-cliff for changelog generation:
# Generate changelog for new version
git cliff --tag v0.6.0 --output CHANGELOG.md
# Tag and push
git tag v0.6.0
git push origin v0.6.0This project is licensed under the MIT License - see the LICENSE file for details.