At NeoSmart Technologies, we’re huge fans of the new Windows Subsystem for Linux,1 and have spent a lot of time trying to make the transition between the native Win32 subsystem and the Linux/WSL subsystem as seamless as possible.
For those of you that haven’t already seen it, we recommend reading our previous article Meet $, your new best friend for WSL for an introduction to WSL and $
, our nifty helper utility that lets you directly run Linux commands in your Windows workflow. In brief, we developed $
(also known – though less affectionately – as RunInBash
) to make it possible to run Linux utilities directly from within a Windows workflow, complete with arguments, stdin
, stdout
, and stderr
redirection, and more.
While $
makes it dead simple to run any Linux command by prefixing it with — yup, you guessed it — $
, sometimes even that isn’t easy enough. For example, a lot of the developers at NeoSmart don’t use bash as their primary shell;2 so having to run another shell, say fish, by keying in +R then having to type in $ fish
, while still a distinct improvement over bash -c fish
, just didn’t cut it. And it’s not just a shell – there are a lot of “stand alone” command line utilities that developers rely on enough to launch directly without first entering a shell, such as ssh
or nvim
.
The ultimate solution we’ve landed on is a simple bash batch script that you can copy locally as many times as you like to launch any Linux tools you desire – without ever writing or changing a line of code.
Let’s jump straight into the batch file and then we’ll talk about how it works:
@echo off
set cmd=%~n0
$ %cmd% %*
Disappointed? Why, were you expecting more? That’s really all there is to it. The batch file above, when copied to a file called, let’s say, ssh.bat
will run ssh
under WSL, forwarding any arguments you pass to it along. All you have to do is put it in your PATH
somewhere!
So how does it work? First, the batch file gets its own name via the %~n0
magic syntax.3 This gives us the file name without the directory component, so in this case, ssh
– which will be taken as the name of the command to run on the Linux side of things.
The rest of the magic is all thanks to $
, which takes care of escaping arguments and passing them to bash.exe
in such a way that you can keep your sanity instead of pulling out your hair trying to figure out how to double-escape an '
in an argument enclosed in "
when your command contains spaces and you need to pass it in to bash -c
enclosed in another… forget it. That’s what $
is there for.
Have another Linux tool you use often? Just copy your ssh.bat
over to tool.bat
and you’ll be on your merry way. If you want to get all fancy, you can even create a symlink instead, and then if you ever want to make some changes to this batch file (though hopefully you’ll never need to) you’ll only need to change one and the rest will automatically follow suit. It really couldn’t get any easier than this.
If you don’t already have $
installed, you can either download it here or install it with chocolatey via choco install RunInBash
.
Since win10 now supports symlinks, why copy the script? Just do what bsuybox does and create symlinks with the command names.
@J that was our inspiration.
As mentioned in the post:
Linux is simply fantastic, I love knowing how to import to my windows