Convert Windows path for Windows Ubuntu Bash

I have a windows batch script that uses Windows Ubuntu Bash. It receives a full Windows path as an argument and then passes that path to a command in Ubuntu Bash.

@echo off
bash -lic 'ffmpeg -i "%1" output.avi'

Here "%1" is the full Windows path, like "C:\some path\file.avi"

The command gives the error:

C:some pathfile.avi: Protocol not found

What can I do to have this Windows path convert to a path like /mnt/c/some\ path/file.avi which the Windows Bash would actually understand?


Windows Build 17046 [1] contains new wslpath utility that can translate paths from/to WSL/Windows. This was known missing WSL feature. [2]

Example usage:

$ echo $0
/bin/bash

$ which wslpath
/bin/wslpath

$ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip

You can call wslpath from Powershell on Windows:

>>> wsl wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip

wslpath options and parameters:

-a    force result to absolute path format
-u    translate from a Windows path to a WSL path (default)
-w    translate from a WSL path to a Windows path
-m    translate from a WSL path to a Windows path, with ‘/’ instead of ‘\\’

I wrote a bat file to do this. Just place the file wherever you are working or add it to your path (or just put it above your code, which would be easier to work with). Remember to assign "variable" to your file path first (if you are using a separate file, try using parameters).

What the code does:

1) Get the first letter of the path, which is the drive.

2) Remove the first two letters.

3) Change the slashes.

4) This is the tricky part: since Linux is case sensitive, we need to convert uppercase drive letter to lowercase. Do this by matching each (tell me if there is a better way). You can remove unnecessary drive letters too, since you probably have no more than ten drives.

5) Combine everything to give the final string.

The result:

Input:

E:\myfiles\app1\data\file.csv

Output (with the quotation marks):

"/mnt/e/myfiles/app1/data/file.csv"

The code is as follows:

@echo OFF

set "variable=E:\myfiles\app1\data\file.csv"

set "drive=%variable:~0,1%"

set variable=%variable:~2%
set "variable=%variable:\=/%"

if %drive%==A set "drive=a"
if %drive%==B set "drive=b"
if %drive%==C set "drive=c"
if %drive%==D set "drive=d"
if %drive%==E set "drive=e"
if %drive%==F set "drive=f"
if %drive%==G set "drive=g"
if %drive%==H set "drive=h"
if %drive%==I set "drive=i"
if %drive%==J set "drive=j"
if %drive%==K set "drive=k"
if %drive%==L set "drive=l"
if %drive%==M set "drive=m"
if %drive%==N set "drive=n"
if %drive%==O set "drive=o"
if %drive%==P set "drive=p"
if %drive%==Q set "drive=q"
if %drive%==R set "drive=r"
if %drive%==S set "drive=s"
if %drive%==T set "drive=t"
if %drive%==U set "drive=u"
if %drive%==V set "drive=v"
if %drive%==W set "drive=w"
if %drive%==X set "drive=x"
if %drive%==Y set "drive=y"
if %drive%==Z set "drive=z"

set "variable=/mnt/%drive%%variable%"

echo "%variable%"

@echo ON

Why so complicated?

Change the registry entry

HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open\command

from

C:\Windows\System32\wsl.exe "%1"

to

C:\Windows\System32\wsl.exe `wslpath '%1'`

Use backticks before wslpath and at the end, and use single quotation marks (straight ticks) around %1.

Works for me.