The final say Windows/Linux Part Finale
Well, the documentation and guides on how to do this are pretty horrible, but I think I’ve finally figured out all the tradeoffs if you want to have a modern development environment (eg Linux) and also use Windows applicatiions because there are some, like Unreal Engine or Airsim, which simply don’t run well without the Windows GUI. So it turns out there are three levels of tradeoffs and you get to decide how deep you want to go that really is about whether you want a single file system and how many commands are Windows underneath or not, so TL;dr:
- Git for Windows. If you just want a thin layer of Bash and mainly want to stay in Powershell, the use Git for Windows which gives you Git Bash and then do some tweaks to get OpenSSH working and symlinks.
- MSys2. If you want to do some installations of some commands that are linux only, then install msys2 and tweak the full paths and the home directory.
- WSL 2. If you want to mainly be in Linux and just Windows for the graphical applications then run a side by side Linux VM.
Git for Window
Git for Windows (aka Git Bash). Ok, this works best if you need bash scripting and environment, but most of your work is in Windows. The name MINGW64 is actually a very good description, it means “Minimal GNU for Window 64-bit). You cannot add more utilities to the “Linux” side, these are fixed, there is no installer, so the trick here is that if you want more tools like “GNU Make”, you install them on the Windows side with tools like Scoop or Choco. What is going on technically here is that you are using CYGWIN underneath, so there are some libraries that are POSIX compliant, so it is fast and you are using the Windows file system. The big trick here is that you need to replace the Windows version of OpenSSH with
choco install openssh and then you need to make sure the paths work properly, that is the default is all Windows commands are overshadowed by Git for Windows paths. And also you need the symlinks enabled. This sort of works so that you can kind of run vi on the Windows side or the Linux side and it running properly. Or for instance if you want to use docker, you do a
scoop install docker and you are using the Windows version of it. And then you have a single set of config files like .ssh.
As an aside, the default this likes to use the OpenSSH client from Windows itself to do the initial installation and it hardcoded in a bunch of places, so either set GIT_SSH to the Choc install of OpenSSH or install OpenSSH as well which you can do with `
Add-WindowsCapability -Online -Name OpenSSH.Client*
As an aside, if you want the hacked version of MSYS2, you can download and install
Git for Windows SDK which will give you Pacman, so it is kind of a cross between Git for Windows and MSYS2 below.
As an aside, MSYS2 means MingGW64 v2. This looks the same but is actually quite different, here you have a different installer “Pacman” from ARCH so you get more customizability, but it is the first one that gives Linux its own file system space. You can configure this so that you are in your Windows home directory instead of
/home/rich living in a different files system and you can also run it quickly from the Windows Powershell by running
msys2. The main trick here is that you have to hack on the Windows side, the magic file MSYS2.ini and enable inherit and also allow symlinks. For instance, if you have installed msys2 with
scoop install msys2 then a quick
Get-Command msys2.cmd shows that you are really running
c:\Users/_yourname_\scoop\apps\msys2\current\msys2_shell.cmd and you can edit msys2.ini there are symlink it into your repo or modify the msys2_shell.cmd to uncomment MSYS=winsysmlinks:nativestrict and MSYS2_PATH_TYPE=inherit. The main drawback here is that pacman -S is different from apt-get on Ubuntu for instance and not all the libraries are there. For instance, Veracrypt isn’t ported.
You can see what exists by doing
pacman -Ss _name_of_package_
If you do not like modifying ini files and I can’t blame you running
msys2_shell.cmd -use-full-path works just as well from PowerShell.
The final way to setup the home directory in MSYS2 is to edit /etc/nsswitch.conf and set
db_home: windows and this does work.
Windows Subsystem for Linux v2
WSL 2. Ok, this is a completely different world which you can check that you have with
wsl -l -v. In this case, you *do not* want to use the native Windows environment for storing files since you are running a true VM under the covers, instead, this is for the case where you are mainly in Linux and only want to run Windows applications or occasionally call out with
powershell _a power shell script_ the advantage here is that you are running native Linux, so the tooling like docker runs there.
Installation is pretty trick here there is supposed to be a
wsl --install option but you need to sign up for Windows insider and this failed with a “multi-tenant` error when I tried to use my Windows Live account. So you have to do it manually.
You can run multiple versions of Linux because it is a real VM and see them with
wslconfig /l on the Windows side and even set defaults.
You manage this with the
wsl command so you can for instance run
wsl and you are in Linux, you can set it to run with your Windows directory, but it will be slow, so you really want everything to run on the Linux side. If you really want to run Windows commands you can have it inherit paths, but most of the time you have the same tooling as real Linux. Also, you have a completely separate world. For instance, you have to setup
~/.ssh/config twice, so instead you can use Symlinks for this, so to use the same .vimrc, you can do a
ln -s /mnt/c/Users/$USER/.vimrc. Note that you can change the directory, but there is a bug in that if you edit /etc/passwd, you cannot just comment out a line and you are going to get bitten by the difference between Windows files which have CRLF and Linux files with CR only., you need to delete it or put it later as it uses that to find the home directory with
wsl -u root vi /etc/passwd
If you do run in this mode, it is convenient if you can have at least some files like .vimrc work correctly so that vi on the Windows side and the Linux side work properly. Also to have .ssh be the same so you can ssh on both sides. In this case, the easy thing to do it to symlink. But because of the various problems with Linux vs Windows files its probably easier just to use git and put your common files in a dotfiles and use git to keep it in sync. That is because Git manages this translation for you automatically which is nice.
The other detail is how to run SSH-Agent. With MSYS2 and Git for Windows, you are using Openssh, so when you remember a key it just works across Windows and Linux. But with this mode, you are working in Ubuntu and you need to install Keychain and manage the keys separately and add
keychain -q --nogui $HOME/..ssh/_your key_ and
source $HOME/.keychain/$HOST-sh and you are done.
Also since this is a true VM, you have to have a big machine with lots of RAM and disk since you are not sharing this stuff with Windows. So if you get into trouble, you reboot the subsystem with
Get-Service LxssManager | Restart-Service
If you forget the password that you have on the Linux side, you have to reset it. This is different than MSYS2 for instance where if you boot from an administrative windows then you get root. So
wsl -u root is like sudo and you can do a
wsl -u root passwd _the user_ and this will set the password for that user on the Linux side.
Now how do you manage the WSL virtual machine from the Windows side? Well first of all there is a magic file called
/etc/wsl.conf which handles a bunch of this for instance and as I mentioned, you can use the /etc/passwd trick if you really want your home to be the Windows file system and don’t mind it being somewhat slow. The automount option is also key. As an aside if you do not like a direct edit, you can run
wsl -u root usermod -d /mnt/c/Users/rich rich which will run that command as the root. You cannot actually run this command yourself while logged in for obvious reasons. There are other tricks like using fstab to do this as a mount, but this usermod is pretty simple.
[automount] # So that Windows /mnt/c passes through file permissions options = "metadata" [filesystem] # the default is zero which means all files aree created 777, we really want 644 umask 022