Closed entosen closed 1 year ago
Unfortunately, by that point in the code, the value of HOME
from windows has already been lost. In order to preserve something like this, the code would need to save a copy of the environment variable before calling into WSL, and “restore” it instead of simply unsetting it. At this point, I’m unsure how we would even know which environment variables should be backed up to be restored…
🤔 So, because of the interaction between windows and linux, there’s no easy solution… not saying someone couldn’t build this functionality, but it would be a bit more complex than a simple small feature—even if the description of the feature is so easy to formulate as you put it well here.
I set HOME environment variable to C:\Users\bob\home by Windows setting.
How exactly?
- In Windows settings, set the %HOME% env var to something else
I guess this can be simulated by HOME being set within WSL, whether set before or not.
- Open wsltty (echo $HOME -> /home/bob)
- $ cmd.exe /c set
- HOME is not shown
The same happens if you run cmd.exe from a WSL default terminal, so sorry, I think this is not a wsltty issue.
OK, now I understand. @entosen you need to use WSLENV variable to pass variable between Windows and WSL, see https://devblogs.microsoft.com/commandline/share-environment-vars-between-wsl-and-windows/
Also here HOME is the actual environment variable in Linux world. It could be overwritten by distribution's own $HOME variable. Instead %USERPROFILE% can be used like this set WSLENV=USERPROFILE/p
.
My understanding is that this is being set through the system environment variables
And it’s not being propagated through WTTY because we clear the HOME
variable before calling a windows program.
Thank you, everyone.
However, it seems that my intentions have not been well conveyed to you.
I have 3 separate directories intended to be as home directory.
C:\Users\bob
Windows Default
C:\Users\bob\.ssh
ignoring HOME environment variable.C:\Users\bob\.vscode
ignoring HOME environment variable.C:\Users\bob\home
for Windows processes (mainly processes in cygwin)
C:\Users\bob\home\_gvimrc
according to HOME environment variable./home/bob
(\\wsl$\Ubuntu\home\bob
) for WSL processes
I intentionally add HOME environment variable to Windows environment setting
What I want is:
C:\Users\bob\home
(2)/home/bob
(3)C:\Users\bob\home
(2)(case1) invoke from PowerShell
> cmd.exe /c set HOME
HOME=C:\Users\bob\home
HOMEDRIVE=C:
HOMEPATH=\Users\bob
(case2) invoke from Cygwin
% echo $HOME
/cygdrive/c/Users/bob/home
% cmd.exe /c set HOME
HOME=C:\Users\bob\home
HOMEDRIVE=C:
HOMEPATH=\Users\bob
(case3) invoke from WSL in wsltty: (HOME is lost !!!)
$ echo $HOME
/home/bob
$ cmd.exe /c set HOME
'\\wsl$\Ubuntu-20.04\home\bob'
CMD.EXE started in the current directory above.
UNC paths are not supported; use the Windows directory by default.
HOMEDRIVE=C:
HOMEPATH=\Users\bob
(case4) invoke from WSL in Windows Terminal
$ echo $HOME
/home/bob
$ cmd.exe /c set HOME
'\\wsl$\Ubuntu-20.04\home\bob'
CMD.EXE started in the current directory above.
UNC paths are not supported; use the Windows directory by default.
HOME=C:\Users\bob\home
HOMEDRIVE=C:
HOMEPATH=\Users\bob
In short, you want to share the same home directory C:\Users\bob\home
between cygwin and WSL, right?
No. I want to separate home directory.
What I want is:
- In windows, HOME points
C:\Users\bob\home
(2)- In WSL, HOME points
/home/bob
(3)- In windows processes invoked from WSL, HOME points
C:\Users\bob\home
(2)
C:\Users\bob\home
and /home/bob
are not same directory. Did you assume the opposite? /home/bob
path is in the distribution in WSL which is totally different than C:\Users\bob\home
.
@Biswa96
C:\Users\bob\hom
e and/home/bob
are not same directory.
I already know that.
The problem I am facing is that windows processes invoked from WSL point to which directory as home directory.
(In other words, the processes read dot-files from which directory.)
I want the processes to point to C:\Users\bob\home
in accordance with HOME environment variable in Windows.
However, Actually, the processes point to C:\Users\bob
because HOME envrionment variable of them is lost.
This behavior (dropping HOME environment variable) occur only in wsltty, In other terminal (wsl original terminal, windows terminal, etc), It does not occur.
What I want is:
- In windows, HOME points C:\Users\bob\home (2)
- In WSL, HOME points /home/bob (3)
- In windows processes invoked from WSL, HOME points C:\Users\bob\home (2)
Now understood. Checking:
See the comment above that unsetenv("HOME"); code. It was added to solve an issue.
(#76) If I disable this unsetenv, the current issue is not solved either, HOME will then be taken from the WSL HOME (path syntax converted).
I either case, behaviour without wsltty appears to be the same, so still no wsltty issue seen.
@mintty
If I disable this unsetenv, the current issue is not solved either, HOME will then be taken from the WSL HOME (path syntax converted).
Would this be accurate?
you wrote in https://github.com/mintty/wsltty/issues/76#issuecomment-351360055,
Apparently, if a Windows application is started from WSL, it inherits the environment from the embedding Windows program, which is the terminal application mintty in this case.
Environment variables in WSL world are not shared to Windows world ? (unless WSLENV is set.)
As I mentioned, we would have to squirrel away the original value of HOME
at startup, and restore that value with a setenv
rather than using unsetenv
. This is a simple to describe feature request, that is actually quite complex in how it could be implemented.
If I disable this unsetenv, the current issue is not solved either. ...
I seem to have misinterpreted my test observations. Actually this change does fix the issue. Now it's only to be evaluated why it was introduced for that other issue and whether a fix for #76 is still needed after 5 years.
Perhaps this is what is happening:
workaround pseudo code:
if (getenv("HOME") does not start with "/cygdrive/" ) {
unsetenv("HOME")
}
Thanks for the analysis. Note that the /cygdrive prefix is reconfigurable and may be just / e.g. in MSYS or Git for Windows. I guess it's better to just check whether HOME was set or not (and unsetenv if it was empty). However, this appears to fix the issue if wsltty was started from a desktop shortcut, but not if mintty --WSL was run from another cygwin shell session. Would that be sufficient?
Actually, HOME is never empty when mintty code is started as it is being set by the cygwin runtime already. So it is still open how to handle the "empty/unset" case.
I think the following clause is needed to tackle the issue, please check:
wchar * HOME = getregstr(HKEY_CURRENT_USER, W("Environment"), W("HOME"));
if (HOME && *HOME)
setenv("HOME", cs__wcstoutf(HOME), true);
else
unsetenv("HOME");
I have tried that code. But it did not work in some cases.
In case that HOME is set to C:\Users\bob\home
in Windows world,
the process invoked from WSL in wsltty has HOME=C:\Users\bob\home
.
This is good.
In another case tha HOME is set to %USERPROFILE%\home
in Windows world,
then HOME=C:\Users\bob\home\%USERPROFILE%\home
. This is wrong.
I don't know why this happens.
How about the following ? Personally, the following would suffice .
wchar * HOME = getregstr(HKEY_CURRENT_USER, W("Environment"), W("HOME"));
if (! HOME || ! *HOME)
unsetenv("HOME");
Your simplified proposal does not work for me, cmd.exe /c echo %HOME%
always says "%HOME%".
You're right, though, that % variable expansion needs to be added. For the records, it's not quite obvious how to test that as it seems impossible to set a literal %...% string in cmd.exe, powershell is needed to achieve it...
I've now uploaded a fix; I hope it's sufficient to handle one initial environment variable.
It looks good to me. Thnak you.
(I tried on Ubuntu in wsltty)
---------------------
(case1: HOME environment variable set with %USERPROFILE% in windows world)
$ reg.exe query 'HKEY_CURRENT_USER\Environment' /v HOME
HKEY_CURRENT_USER\Environment
HOME REG_EXPAND_SZ %USERPROFILE%\home
$ cmd.exe /c echo %HOME%
C:\Users\bob\home
---------------------
(case2: HOME environment variable set by absolute path in windows world)
$ reg.exe query 'HKEY_CURRENT_USER\Environment' /v HOME
HKEY_CURRENT_USER\Environment
HOME REG_SZ C:\Users\bob\home
$ cmd.exe /c echo %HOME%
C:\Users\bob\home
---------------------
(case3: HOME environment variable is not set in windows world)
$ reg.exe query 'HKEY_CURRENT_USER\Environment' /v HOME
error: not found
$ cmd.exe /c echo %HOME%
%HOME%
Released 3.6.4.
relate to #84
I set HOME environment variable to
C:\Users\bob\home
by Windows setting.When I invoke windows exe from WSL in WSLTTY, HOME environment is lost and exe points
C:\Users\bob
as default home.I want to keep HOME env variable
C:\Users\bob\home
.problem code is here https://github.com/mintty/mintty/blob/7fbb245df1128a5e7252b3bb49703620cc8fb1d7/src/winmain.c#L6231-L6233
my environment:
Reproduction:
Thanks