Module which allows you to run bash commands and other Linux programs from the Windows Subsystem for Linux directly from PowerShell, with support for piping to and from PowerShell commands.
Ensure you are running a recent Windows 10 Insiders build (>14316), and set up the Subsystem for Linux.
Grab the necessary files by cloning this repo:
git clone https://github.com/jimmehc/PowerBash.git
And import the PowerBash module (PowerShell doesn't like function names like "apt-get", so pass the
-DisableNameChecking switch to avoid that warning message):
Import-Module PowerBash\PowerBash.psm1 -DisableNameChecking
PowerBash is also available via the PowerShell Gallery:
Install-Module PowerBash Import-Module PowerBash -DisableNameChecking
What Commands Are Available?
PowerBash looks in locations in the Linux Subsystem's filesystem for programs, equivalent to the following
This is currently hardcoded, although I plan on making it configurable in future.
Any existing commands available to the current PowerShell session, including EXEs in the PowerShell
$env:PATH, cmdlets, functions, and aliases, will not be overridden by Linux programs. If you would like to use a Linux program of the same name instead, remove all functions, cmdlets, and aliases from your session prior to importing the module. For EXEs, you can pass the names of the programs you want overriden to the module via
-ArgumentList when importing (comma separated).
sort is an alias for
Sort-Object in PowerShell, and the Win32 utility,
sort.exe, is normally on your
$env:PATH. To use the Linux
sort utility instead, first remove the PowerShell alias:
Remove-Item alias:sort -Force
And then import PowerBash, passing
Import-Module PowerBash\PowerBash.psm1 -DisableNameChecking -ArgumentList "sort"
apt-get is treated specially. Whenever
[sudo] apt-get install ... is run, PowerBash is reloaded, causing the newly installed program to be instantly available.
Converting Paths from Windows to Linux Versions
lxp) is provided, to allow easier conversion between Windows versions of paths and the Linux equivalents.
For convenience, I've added a PSReadLine key handler for Alt-L, which will change Windows paths to Linux paths in place in the console:
ConvertTo-LinuxPath is a quick and dirty implementation. It probably doesn't handle all escaping properly.)
When imported, PowerBash locates available Linux programs, and adds a wrapper for each one. Each wrapper handles pipe input and other arguments, and launches something like
bash.exe -c "$Program $Args < $PipeArgs". Note that this incurs the performance overhead of launching a new
bash.exe process for every command.
This bug (UserVoice page) currently makes it impossible to connect the
bash.exe process` stdin/stdout/stderr to anything other than the console, which means piping directly to and from it cannot be done. As a consequence, PowerBash is designed around avoiding any scenario where PowerShell will try to redirect the input or output streams.
Unfortunately, this requires the use of temporary files for communication between PowerShell and the Linux Subsystem, which hurts performance. In playing with it myself, I haven't found it noticeable, but YMMV.
It was also necessary to add some hacky command introspection, involving examining ASTs to determine whether or not PowerShell will redirect the output of
bash.exe somewhere other than the console, which allows interactive apps to function alongside those used in pipelines. While I think I've covered most common scenarios with this, I have no doubt that there are some ways in which this breaks. If you see
Error: 0x80070057 after running a command, please open a bug.