How to get the host user home directory in WSL Bash

With wslpath and wslvar:

$ wslpath "$(wslvar USERPROFILE)"
/mnt/c/Users/felipesantos

You may launch cmd.exe from bash to get the host environment variables. In the following, win_userprofile has your answer, and the other variables are for completeness.

win_userprofile="$(cmd.exe /c "<nul set /p=%UserProfile%" 2>/dev/null)"

win_userprofile_drive="${win_userprofile%%:*}:"
userprofile_mount="$(findmnt --noheadings --first-only --output TARGET "$win_userprofile_drive")"

win_userprofile_dir="${win_userprofile#*:}"

userprofile="${userprofile_mount}${win_userprofile_dir//\\//}"

Sources : Craig Loewen at Microsoft and Michael Hoffman.


Fortunately since Windows 10 build 17063 (included in Windows 10 1803) there is a more straightforward way of sharing environment variables between Windows and WSL - WSLENV.

To make %USERPROFILE% accessible in WSL you list the variable name in the WSLENV variable. If you are not using WSLENV yet then just run the following command once in a cmd.exe session. The command setx permanently writes variables to the master environment in the Windows registry:

setx WSLENV USERPROFILE/up

This WSLENV setting will cause WSL to make %USERPROFILE% from Windows accessible as $USERPROFILE in WSL shell. The Windows directory path will be converted to the Unix format. If you do not want to convert the path, just omit the p:

setx WSLENV USERPROFILE/u

If you need to transfer multiple variables separate them by a colon. More details:

  • https://docs.microsoft.com/en-us/windows/wsl/interop#share-environment-variables-between-windows-and-wsl
  • https://devblogs.microsoft.com/commandline/share-environment-vars-between-wsl-and-windows/

I use the variable in my cdw function (cd to Windows path). I define it in ~/.bash_aliases which is executed automatically in Ubuntu:

#!/bin/bash

cdw () {
        if test "$#" -eq 0 ; then
                cd "$USERPROFILE"
        elif test "$1" = - ; then
                cd "$1"
        else
                cd -- "$(wslpath "$@")"
        fi
}