Skip to content

Instantly share code, notes, and snippets.

@fun4jimmy
Last active May 27, 2017 12:59
Show Gist options
  • Save fun4jimmy/40b2b115cd574c66a4bf624fdcb4bc1f to your computer and use it in GitHub Desktop.
Save fun4jimmy/40b2b115cd574c66a4bf624fdcb4bc1f to your computer and use it in GitHub Desktop.
Python module to transform path arguments to Windows binaries from WSL (Windows Subsystem for Linux) bash shells.

Synopsis

This python module forwards calls to Windows binaries from WSL (Windows Subsystem for Linux) bash shells also converting any path style arguments starting with /mnt/ to their Windows equivalent. Without this conversion the Windows binaries will attempt to open Linux file paths and fail.

Code Example

Invoking Sublime Text 3 from a WSL bash prompt:

$ wslexeshim.py "/mnt/c/Program Files/Sublime Text 3/subl.exe" -n -w /mnt/d/README.md

Setting the git text editor to Sublime Text 3:

$ git config --global core.editor "wslexeshim.py '/mnt/c/Program Files/Sublime Text 3/subl.exe' -n -w"

Example .hgrc to set the Mercurial text editor to Sublime Text 3:

[ui]
editor = wslexeshim.py "/mnt/c/Program Files/Sublime Text 3/subl.exe" -n -w

Motivation

Setting the preferred editor for version control systems (eg. Git, Mercurial) within a WSL session to a Windows binary causes the version control system to invoke the editor with Linux style paths. As the Windows binary text editor is expecting Windows style paths this causes it to open the wrong file or even fail completely.

This python module was written to act as a shim around the Windows text editor and convert the paths before invoking the executable.

#!/usr/bin/env python
'''Module for forwarding windows commands from a Windows subsystem for Linux (WSL) bash prompt to Windows
'''
import os
import re
import subprocess
import sys
_MNT_DRIVE_REGEX = re.compile(r'\/mnt\/([a-z])\/')
def convert_to_windows_path(path):
'''Takes a WSL path beginning with "/mnt/" and converts it to its windows equivalent.
eg. "/mnt/c/Program Files/Sublime Text 3/subl.exe" -> "c:\Program Files\Sublime Text 3\subl.exe"
'''
windows_path = ''
mnt_drive_match = _MNT_DRIVE_REGEX.match(path)
if mnt_drive_match:
windows_path = mnt_drive_match.group(1)
windows_path += ':\\'
windows_path += path[mnt_drive_match.end(0):]
else:
# todo: handle network paths and other mount types
raise ValueError("Cannot convert unsupported mount type '{0}', only drive letter mounts are supported.".format(path))
windows_path = windows_path.replace(os.sep, '\\')
return windows_path
def main(argv):
'''Calls the given command and arguments converting each path style argument beginning with "/mnt/" to
its windows equivalent.
This allows windows executables to find files specified as command arguments. For example the following
command from a WSL bash prompt:
wslexeshim.py "/mnt/c/Program Files/Sublime Text 3/subl.exe" -n -w /mnt/d/Readme.txt
Would transform to:
/mnt/c/Program Files/Sublime Text 3/subl.exe" -n -w d:\\Readme.txt
This allows the windows version of sublime text to find and open the correct Readme.txt file.
'''
if len(argv) < 1:
raise RuntimeError('Not enough arguments to {0}: expected at least 1, got 0.'.format(__file__))
command = [argv[0]]
argv = argv[1:]
for arg in argv:
if arg.startswith("/mnt/"):
arg = convert_to_windows_path(arg)
command.append(arg)
subprocess.call(command)
if __name__ == '__main__':
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment