How to get the host user home directory in WSL Bash
Become or hire the top 3% of the developers on Toptal https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Romantic Lands Beckon
--
Chapters
00:00 Question
00:50 Accepted answer (Score 37)
01:04 Answer 2 (Score 9)
02:39 Answer 3 (Score 5)
03:11 Answer 4 (Score 4)
04:53 Thank you
--
Full question
https://superuser.com/questions/1271205/...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#windowssubsystemforlinux
#avk47
ACCEPTED ANSWER
Score 39
With wslpath
and wslvar
:
$ wslpath "$(wslvar USERPROFILE)"
/mnt/c/Users/felipesantos
ANSWER 2
Score 9
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
}
ANSWER 3
Score 5
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.
ANSWER 4
Score 4
Since my writing of this question, wslpath
has been added to (to my knowledge) all WSL/LXSS distributions. This program can translate windows paths to the corresponding mount point on the Linux subsystem, therefore the easiest solution would be now:
export WINHOME=$(wslpath $(cmd.exe /C "echo %USERPROFILE%" 2>/dev/null | tr -d '\r'))
# echo $WINHOME prints something like /mnt/c/Users/dualed
wslpath
documentation is still sparse:
$> man wslpath
# No manual entry for wslpath
# See 'man 7 undocumented' for help when manual pages are not available.
$> wslpath --help
wslpath: unrecognized option: -
wslpath: Invalid argument
Usage:
-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 '\'
EX: wslpath 'c:\users'
Notes
- Windows commands often add carriage-return to the output which is also not removed by
wslpath
, and so may end up in the Linux output,tr -d '\r'
gets rid of that - For some time now,
cmd.exe
will print a warning message to stderr that it was started from an invalid directory, the2>/dev/null
part removes that
Currently I'm using a small helper to retrieve any windows environment variable
#!/bin/bash
# 'winenv'
cmd.exe /C "echo %$*%" 2>/dev/null | tr -d '\r'
And using it like this
WINHOME=$(wslpath "$(winenv USERPROFILE)")