Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native wsl shell behaves differently from ssh login to wsl #4911

Closed
DrVanScott opened this issue Feb 20, 2020 · 23 comments
Closed

Native wsl shell behaves differently from ssh login to wsl #4911

DrVanScott opened this issue Feb 20, 2020 · 23 comments
Labels

Comments

@DrVanScott
Copy link

DrVanScott commented Feb 20, 2020

If I start a native WSL shell, i can

  • echo the content of $WSLENV as it is defined in the windows environment variables
  • start windows programms e.g. cmd.exe

If i login to WSL via ssh, both of these actions behave not the same

  • WSLENV is empty
  • cmd.exe is not found

The latter issue can be worked around by using "/windows/system32/bash.exe --login" as login shell
Any workarounds to solve both issues higly recommended.

EDIT: Solution can be found here: #4911 (comment)

@therealkenc
Copy link
Collaborator

WSLENV is empty

Same as this and similar.

Several approaches, most common being ~/.ssh/environment. Remember to set PermitUserEnvironment yes in your /etc/ssh/sshd_conf.

The latter issue can be worked around by using "/windows/system32/bash.exe --login" as login shell

I could not follow this sentence, but not being able to follow academic in the context. The reason cmd.exe was not found is because /mnt/c/WINDOWS/system32 is not in your $PATH. One possible approach would be to turn off %PATH% marshaling in /etc/wslconf with appendWindowsPath=false and then append the paths you want in .bash_profile.

These are not work-arounds, they are by-design ssh/sshd.

@DrVanScott
Copy link
Author

Maybe i was not clear.

On a "standard" linux system there is not much of a difference whether you login "local" or remote via ssh. I am not saying that there are no differences at all, but at least most of the environment variables are identicall. This is also for PATH

Unfortunately this is different for WSL: If you start a local shell, %PATH% is "injected" into the shell. Also WSLENV is taken into account. If you login via ssh, this is not the case.

If this cannot be fixed by default, is it possible to somehow activate this mechanism optionally?

What/where is the magic that a "local" login shell do special handling for PATH and is also interpreting WSLENV?

The latter issue can be worked around by using "/windows/system32/bash.exe --login" as login shell

If you replace the standard shell /bin/bash in the passwd file to >mntp>/windows/system32/bash.exe, at least the PATH is initialized according to %PATH%. I thought, that system32/bash is part of WLS but as of now i think i am wrong, so I cannot really recommend this anymore

@ad-on-is
Copy link

ad-on-is commented Feb 21, 2020

Maybe i was not clear.

On a "standard" linux system there is not much of a difference whether you login "local" or remote via ssh. I am not saying that there are no differences at all, but at least most of the environment variables are identicall. This is also for PATH

Unfortunately this is different for WSL: If you start a local shell, %PATH% is "injected" into the shell.

You face the same problem when you try to ssh into a Linux VM, running inside another Linux, which would represent a similar scenario as WSL . For example, running Alpine as a VM on top of Ubuntu! You won't be able to access Ubuntus $PATH and Ubuntus executables from within Alpine.

@DrVanScott
Copy link
Author

You won't be able to access Ubuntus $PATH and Ubuntus executables from within Alpine.

But that's exactly what's actually happening if you start a WSL shell on Windows - not using ssh: You will find a $PATH which contains host related pathes:

Microsoft Windows [Version 10.0.18362.592]
(c) 2019 Microsoft Corporation. Alle Rechte vorbehalten.

C:\>wsl
~$ echo $PATH | tr : "\n" | grep -i system32
/mnt/c/WINDOWS/system32
/mnt/c/WINDOWS/System32/Wbem
/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/
/mnt/c/WINDOWS/System32/OpenSSH/
~$ exit
logout

C:\>ssh user@windowhostname
~$ echo $PATH | tr : "\n" | grep -i system32
~$ exit

In both cases i start on the HOST system and start a shell on the guest. But the environments are different. The same difference applies for $WSLENV and all variables specified within WSLENV

I am not against this special handling of PATH end WSLENV. It is quite usefull in sharing things between the two worlds. I just wonder how to achieve the same (or similar) when "entering wsl" via ssh

@therealkenc
Copy link
Collaborator

therealkenc commented Feb 21, 2020

Maybe i was not clear.

You were pretty clear except for the part about putting a win32 program in your /etc/passwd.

If you start a local shell, %PATH% is "injected" into the shell. Also WSLENV is taken into account. If you login via ssh, this is not the case.

Correct. This is by-design ssh.

If this cannot be fixed by default, is it possible to somehow activate this mechanism optionally?

"This" behavior of ssh is not broken.

You can coerce ssh to pass an environment variable from client to server with ssh -o SendEnv. Or you can use ~/.ssh/environment as previously stated, which is probably more common.

image

There are other approaches as well.

What/where is the magic that a "local" login shell do special handling for PATH and is also interpreting WSLENV?

The magic happens in wsl.exe (on the Windows side) and WSL /init (on the Linux side). WSL /init spends most of it's time quietly waiting for incoming connections from wsl.exe. Neither are invoked when you run ssh on the client side, and by extension an sshd instance on the Linux side. Same goes for telnet/telnetd, rsh/rshd, or anything else that might be listening on an AF_INET socket in Linux. Those daemons are not part of WSL. They are part of your Linux distribution.

If you replace the standard shell /bin/bash in the passwd file to mnt/windows/system32/bash.exe

Windows .../system32/bash.exe is not a shell. That win32 application was most unfortunately named, and is deprecated. The new mechanism, wsl.exe, is also not a shell. Linux bash, csh, ksh, dash, zsh, fish et al are shells. Putting bash.exe in /etc/passwd as your login shell is a little like making notepad.exe your login shell. Making a long and academic story short: don't set bash.exe (or any other windows program) as your Linux shell.

@ad-on-is
Copy link

Just out of curiosity... why would you even want to ssh into WSL, when you can have all the functionality available directly?

@DrVanScott
Copy link
Author

DrVanScott commented Feb 21, 2020

Just out of curiosity... why would you even want to ssh into WSL, when you can have all the functionality available directly?

Because i often work remotely on that system. As i am more linux than windows, i love to work in terminals and RDP is not really an option. For many years i have been using Cygwin and was quite happy despite "its" huge fork problem... Then i tried to switch to WSL. I currently use Ubuntu, VcXserv and Terminator and i am quite happy. I use WSLENV to share some variables like JAVA_HOME and MAVEN_HOME in combination with some little helpers. This way i can use the Windows-installed versions of Java and Maven. I don't like to have each installed twice and need to keep them in sync. All this works very good in "local" WSL. Of course i can use things like ,ssh/environment to fill the gaps, but then again i am duplicating configuration.

So i am very thankfull for all the input of you both so far :-)

I am currently trying to implement a workaround (and of course will post it here once it would work), but currently have an issue with part of the solution. Here's how to reproduce:

  1. start openssh-server in WSL
  2. Start a cmd.exe and ssh into WSL
  3. Run the command

/mnt/c/Windows/System32/cmd.exe /C echo test

Unfortunately this freezes the konsole. Is it possible to make this work? Interesting fact: If i ssh into WSL from a real linux server (or maybe it is just because it is a different host and not the host running WSL), then the above command works and returns.

@ad-on-is
Copy link

ad-on-is commented Feb 21, 2020

Wow, a hell of a setup you've there. I'd suggest to reconsider that. WSL isn't actually intended to be used with VcXserv since it's not optimized performancewise for that.

Maybe moving your entire setup to WSL only, and switching to VSCode might be a solution.

I'm not a Java developer and don't know if it provides all the necessary things you need, but take a look here.
https://code.visualstudio.com/docs/languages/java

Also, VSCode has a great remote extension which let's you work directly in WSL or via ssh. So when you're on your Windows machine you can use VSCode directly with WSL. When you're remote, you can ssh with VSCode into your WSL.

@therealkenc
Copy link
Collaborator

start openssh-server in WSL
Start a cmd.exe and ssh into WSL
Run the command
/mnt/c/Windows/System32/cmd.exe /C echo test

I was able to reproduce the above.

image

Noting that bringing up unrelated topic under the same issue umbrella usually ends badly. That'd be a pretty legit submission given a filled out bug template.

FWIW I am pretty sure I've tried this scenario in a past life and it worked. This might be a regress. Or I am imagining having tried. Which is also a pretty good possibility.

This does work:

image

Critical difference in scenarios being, that's a Linux ssh client not the Windows ssh.exe client. I suspect (but can't prove) this is going to be a ConPTY thing. If it was WSL, then the latter scenario would fail too. Both scenarios have the same sshd on the receiving end, naturally.

@therealkenc
Copy link
Collaborator

therealkenc commented Feb 24, 2020

/mnt/c/Windows/System32/cmd.exe /C echo test
Unfortunately this freezes the konsole.

That particular issue is addressed with Win32-OpenSSH version 8 available here.

The sensible (or at least pragmatic) answer to the OP remains quoth "append the Windows path yourself in .bash_profile". Something like:

# this is .bash_profile
if [ -n "$SSH_CLIENT" ]; then
  export PATH=$PATH:/mnt/c/Windows/System32:/mnt/c/other/places
fi

Or if one were inclined, schmancy:

function wslpathenv {
    pushd /mnt/c > /dev/null
    winpath=$(/mnt/c/Windows/System32/cmd.exe /c echo %PATH%)
    popd > /dev/null
    winpath=$(echo $winpath | sed 's/ /\?/g')
    components=($(echo "$winpath" | tr ';' '\n'))
    for component in "${components[@]}"; do
        wslcomp=$(/bin/wslpath -u $component)
        wslwinpath="${wslwinpath}"$wslcomp:
    done
    wslwinpath=$(echo $wslwinpath | sed 's/\?/ /g')
}

if [ -n "$SSH_CLIENT" ]; then
    wslpathenv
    export PATH=$PATH:$wslwinpath
fi

image

YRMV.

@DrVanScott
Copy link
Author

Hi @therealkenc , thanks for your answer. Based on your idea to have an scripted solution I developed an own script which not only takes PATH intro account but also correctly handles WSLENV (inluding the /u, /w, /p and /l options). See https://devblogs.microsoft.com/commandline/share-environment-vars-between-wsl-and-windows/ for more information about WSLENV.
The script seems not to run into the blocking issue and i assume it is because it only runs cmd.exe from a subshell and output is not written directly to the console. It uses some vbscript as i didn't found another way to get access to the complete set of environment variables.

Add the following code somewhere at the beginning of your .bash_profile:

if [[ -n "${SSH_CLIENT}" ]]; then
#source the output of the following code. this construct is mainly to have those functions temporarily in a subshell
. <(
function translatePath {
   local WINVAL="$1"
   echo "$(/bin/wslpath -u "$WINVAL")"
}
function translateList {
    local LIST="$1"
    while read -r component; do
      TRANSLIST="${TRANSLIST}""$(translatePath "$component")":
    done < <(echo "$LIST" | tr ';' '\n')
    echo "$TRANSLIST"
}

function getWinPath {
    echo "$(/mnt/c/Windows/System32/cmd.exe /c echo %PATH%)"
}

function getWinVar {
    local WINVAR="$1"

    VBS=$(mktemp -p "$HOME" .XXXXXXX.vbs)
    cat > "$VBS" << INP
Set oShell = WScript.CreateObject("WScript.Shell")
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
Set oEnv=oShell.Environment("User")
var = oEnv.Item( "$WINVAR" )
If var = Empty Then
  Set sEnv=oShell.Environment("System")
  var=sEnv.Item( "$WINVAR" )
End If
stdout.WriteLine(var)
INP
    VBSWIN=$(wslpath -wa $VBS)

    echo "$(/mnt/c/Windows/System32/cmd.exe /c cscript /b "$VBSWIN")"
    rm -rf "$VBS"
}

function doOptionL {
    local VAL="$1"
    echo "$(translateList "$VAL")"
}

function doOptionP {
    local VAL="$1"
    echo "$(translatePath "$VAL")"
}

export WSLENV="$(getWinVar WSLENV)"
echo export PATH=\""$PATH:$(doOptionL "$(getWinPath)")"\"
echo export WSLENV=\""$WSLENV"\"

IFS=':' read -ra VARS <<< "$WSLENV"
for i in "${VARS[@]}"; do
  IFS='/' read -r var opt <<< "$i"
  if [[ $opt = *w* ]]; then
    : #ignore
  elif [[ -z $opt || $opt == u ]]; then
    echo export \""$var"\"=\""$(getWinVar "$var")"\"
  elif [[ $opt == *p* ]]; then
    echo export \""$var"\"=\""$(doOptionP "$(getWinVar "$var")")"\"
  elif [[ $opt == *l* ]]; then
    echo export \""$var"\"=\""$(doOptionL "$(getWinVar "$var")")"\"
  else
    echo unsupported case for  >&2
  fi
done
)
fi

Looks like

grafik

There is some issue with the vbscript code: It doesn't expand placeholders used within the environment variables values, e.g. ComSpec would resolve to %SystemRoot%\system32\cmd.exe and not to C:\WINDOWS\system32\cmd.exe. My knowledge in Windows is too limited and i am not sure if it is possible to use ExpandEnvironmentStrings or how to do it right (the latter wont return the value of WSLENV, which i have defined as a User variable...) So improvements regarding the VBScript are highly appreciated!

@therealkenc
Copy link
Collaborator

therealkenc commented Feb 29, 2020

There is some issue with the vbscript code

For getWinVar try:

cmd="/mnt/c/Windows/System32/cmd.exe"

function getwinvar {
    local winvar=$1
    pushd /mnt/c > /dev/null
    value=$("$cmd" /c echo "%$winvar%")
    popd > /dev/null
    echo $value 
}

echo $(getwinvar ComSpec)
echo $(getwinvar TEMP)

image

Noting, critically, that I don't personally advocate doing anything like this. I'd (in arguendo1) set $MAVEN_HOME in ~/.ssh/environment. I don't personally use $WSLENV either, for the same reason. I'm barely tolerant of appendWindowsPath=true.

[1As an aside, calling Windows Java from WSL is a red flag, but okay free country and that's not your ask.]

@DrVanScott
Copy link
Author

DrVanScott commented Feb 29, 2020

For getWinVar try:

For some reasons this does not work for WSLENV (tested with having no .bash_profile at all, just your code):

$ echo $(getwinvar WSLENV)
%WSLENV%

[1As an aside, calling Windows Java from WSL is a red flag

Such lilke calling Linux software/WSL from within Windows :-P No seriously, why is this a red flag?

@therealkenc
Copy link
Collaborator

For some reasons this does not work for WSLENV

image

Such lilke calling Linux software/WSL from within Windows :-P

Also a red flag.

No seriously, why is this a red flag?

Because you're likely to end up burning hours and hours on a time sink exercise like this unnecessarily ref #4082 (message).

@DrVanScott
Copy link
Author

DrVanScott commented Mar 1, 2020

Hi @therealkenc

in your last post you've used wsl.exe to start bash, but not ssh. A login via ssh looks like this for me: (WSLENV is a environment variable in USER space on my system. Maybe the ´cmd.exe /C echo %VAR%` trick only works for SYSTEM?)

C:\>echo %WSLENV%
JAVA_HOME/p:MAVEN_HOME/p

C:\>ssh xxx@localhost
xxx@xxx:~$ ./getvariable.sh
ComSpec: C:\WINDOWS\system32\cmd.exe
TEMP: C:\Users\xxx\AppData\Local\Temp
WSLENV: %WSLENV%
xxx@xxx:~$ exit
logout
Connection to localhost closed.

C:\>set WSLENV=foo

C:\>echo %WSLENV%
foo

C:\>ssh xxx@localhost
xxx@xxx:~$ ./getvariable.sh
ComSpec: C:\WINDOWS\system32\cmd.exe
TEMP: C:\Users\xxx\AppData\Local\Temp
WSLENV: %WSLENV%

This is different with vbscript approach.

@therealkenc
Copy link
Collaborator

therealkenc commented Mar 1, 2020

Right I see what is going on there. If you actually want to marshal local environment variables from the client, use ssh -o SendEnv (or equivalently .ssh/config on the client) as mentioned earlier.

Alternately you need setx, because the cmd.exe shell being invoked is not the cmd.exe you came from. Indeed, the ssh you came from might be a MacBook in Timbuktu.

It gets worse. Since we are evoking cmd.exe with interop, and the Linux-side $WSLENV isn't set, the Windows %WLSENV% gets actively translated to not being set on the Windows side, by design.

image

This is different with vbscript approach.

I can't get the "vbscript approach" to work with a local cmd set (nor would I expect it to, which is okay). That script is in effect going out to the registry. Since we're talking the cray cray, I guess you could do that. Maybe something like:

powershell="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
function getwslenv {
    pushd /mnt/c > /dev/null
    local value=$("$powershell" "Get-ItemProperty -Path HKCU:\Environment -Name WSLENV | Select-Object -ExpandProperty WSLENV")
    popd > /dev/null
    echo $value
}
echo $(getwslenv)

image

[edit] To clarify, you'd (in the hypothetical) boostrap WSLENV with getwslenv(), but get every other variable using getwinvar(); with cmd.exe echo doing the magic f.e. %ComSpec% expansion for all the not-WSLENV variables. The WSLENV variable is singularly unique, because it is only variable deliberately clobbered (by-design) via WSL interop.

@therealkenc
Copy link
Collaborator

On reflection, it is not obvious to me why, if one were doing the magic WSLENV /u, /w, /p, /l parsing manually, why one would store WSLENV, once, in HKCU/Environment, and then go to the trouble to fetch it as a special case; when one could store a WSLENV, once, in .bash_profile.

export WSLENV=JAVA_HOME/p:MAVEN_HOME/p

IFS=':' read -ra VARS <<< "$WSLENV"
for i in "${VARS[@]}"; do
# ... many things

@DrVanScott
Copy link
Author

DrVanScott commented Mar 2, 2020

Right I see what is going on there. If you actually want to marshal local environment variables from the client, use ssh -o SendEnv (or equivalently .ssh/config on the client) as mentioned earlier.

This is not my point. I don't want to have local variables on the remote side. I just want to have the environment in shells running on that host to be the same, independetly of logging in on that host via ssh or "locally" via wsl.exe.

Alternately you need setx, because the cmd.exe shell being invoked is not the cmd.exe you came from. Indeed, the ssh you came from might be a MacBook in Timbuktu.

Dito: This is not about temporarily "set" variables. It's just about the base environment, so only those variables which are available if you just open an ordinary local cmd.exe.

It gets worse. Since we are evoking cmd.exe with interop, and the Linux-side $WSLENV isn't set, the Windows %WLSENV% gets actively translated to not being set on the Windows side, by design.

Good point! :-)

I can't get the "vbscript approach" to work with a local cmd set (nor would I expect it to, which is okay). That script is in effect going out to the registry.

Yes, it is only ment for the base environment variables.

To clarify, you'd (in the hypothetical) boostrap WSLENV with getwslenv(), but get every other variable using getwinvar(); with cmd.exe echo doing the magic f.e. %ComSpec% expansion for all the not-WSLENV variables. The WSLENV variable is singularly unique, because it is only variable deliberately clobbered (by-design) via WSL interop.

As i wrote before, i cannot get getwinvar() work for USER environment variables, even asite from WSLENV (keep in mind to test this from a bash started via ssh...). As far as i see, it only works for SYSTEM variables, no?
Do you see any chance to get the powershell approach working for all variables?

... when one could store a WSLENV, once, in .bash_profile.

I am not sure if i understand this approach: If i would define it only in .bash_profile, then this would only work for cmd.exe instances, started from within WSL. The same then also applies to those variables mentioned within WSLENV. I think the whole mechanism is based on the fact, that there is a HOST and GUEST system.
This is all about not having things defined twice. I just hate that. And it would not be enought to just hold WSLENV in two different places (windows env settings / .bash_profile, or only within .bash_profile), Also all varialbes present in the value of WSLENV, need to be declared twice.

In my opinion, it would be best if wls.exe wouldn't do any PATH or WSLENV magic. Instead there should be something like a "wsl-injectenv.exe". Then it would be up to user to have it executet in its .bash_profile. As a result the environment would be the same for all bash instances, be them locally instantiated or from remote.

This has been quite a long discussion right now, and I am quite thankfull that you still keep track, btw... :-)

@therealkenc
Copy link
Collaborator

therealkenc commented Mar 2, 2020

If i would define it only in .bash_profile, then this would only work for cmd.exe instances, started from within WSL.

No. It is equivalent to fetching the keys (sic) enumerated in WSLENV from the registry. The other direction isn't applicable, because you don't have Java on WSL, and even if you did, JAVA_PATH would have a different value.

This is all about not having things defined twice.

[What this is all about is... redacted :).] The keys (sic) you want injected would be defined once, since there's no reason to define WSLENV in the registry as a HKCU/Environment variable. Your Windows Java does not care that WSLENV exists. It cares that JAVA_PATH exists (and it does).

In any case fetch WSLENV from the registry and parse it if you insist; this is your workflow after all. You have to define the keys you want injected somewhere once. Your poison where.

As i wrote before, i cannot get getwinvar() work for USER environment variables

I cannot reproduce this. That's why I picked HKCU/Environment %TEMP% as the previous (albeit botched) example. Here's %OneDrive% and %TEMP%:

image

image

Noting that getting User and System variables to take can be a PITA, because they're cached all over creation. When in doubt, reboot.

Instead there should be something like a "wsl-injectenv.exe"

You mean eval /usr/bin/wsl-injectenv MAVEN_PATH JAVA_PATH. That's what you're writing. Bonus if you do it in C/C++ rather than as a shell script (or Python), and post the result to github and as a Ubuntu PPA.

This has been quite a long discussion right now, and I am quite thankfull

YW happy to keep at it.

@DrVanScott
Copy link
Author

Noting that getting User and System variables to take can be a PITA, because they're cached all over creation. When in doubt, reboot.

Reboot was not required, but i always thought it would be enough to restart the "starting point" of my experiments after modifiying some windows environment variables. In my case, the starting point is the first cmd shell from which i run the ssh command. But i was wrong: The cmd.exe started from within wsl is a child of the wsl system. As long as this system is not restarted, environment changes are hidden. So, closing all wsl dependen windows/processes (including sshd) is required.

Interestingly, the vb code does not suffer from this.

Thanks again for you patience. After some testing period i will post my final solution here. Maybe there are some other crazy people like me... ;-)

@DrVanScott
Copy link
Author

Here is my final solution. Add at the beginning of .bash_profile

#!/bin/bash

if [[ -n "${SSH_CLIENT}" ]] && grep -q '([email protected])' /proc/version ; then
#source the output of the following code. this construct is mainly to have those functions temporarily in a subshell
. <(
function translatePath {
   local WINVAL="$1"
   /bin/wslpath -u "$WINVAL"
}
function translateList {
    local LIST="$1"
    while read -r component; do
      TRANSLIST="${TRANSLIST}""$(translatePath "$component")":
    done < <(echo "$LIST" | tr ';' '\n')
    echo "$TRANSLIST"
}

function getWinPath {
    /mnt/c/Windows/System32/cmd.exe /c echo %PATH%
}

function getWinVar {
    local WINVAR="$1"

    VBS=$(mktemp -p "$HOME" .XXXXXXX.vbs)
    cat > "$VBS" << INP
Set oShell = WScript.CreateObject("WScript.Shell")
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
Set oEnv=oShell.Environment("User")
var = oEnv.Item( "$WINVAR" )
If var = Empty Then
  Set sEnv=oShell.Environment("System")
  var=sEnv.Item( "$WINVAR" )
End If
stdout.WriteLine(oShell.ExpandEnvironmentStrings( var ))
INP
    VBSWIN=$(wslpath -wa "$VBS")

    /mnt/c/Windows/System32/cmd.exe /c cscript /b "$VBSWIN"
    rm -rf "$VBS"
}

function doOptionL {
    local VAL="$1"
    translateList "$VAL"
}

function doOptionP {
    local VAL="$1"
    translatePath "$VAL"
}

export WSLENV="$(getWinVar WSLENV)"
echo export PATH=\""$PATH:$(doOptionL "$(getWinPath)")"\"
echo export WSLENV=\""$WSLENV"\"

IFS=':' read -ra VARS <<< "$WSLENV"
for i in "${VARS[@]}"; do
  IFS='/' read -r var opt <<< "$i"
  if [[ $opt = *w* ]]; then
    : #ignore
  elif [[ -z $opt || $opt == u ]]; then
    echo export \""$var"\"=\""$(getWinVar "$var")"\"
  elif [[ $opt == *p* ]]; then
    echo export \""$var"\"=\""$(doOptionP "$(getWinVar "$var")")"\"
  elif [[ $opt == *l* ]]; then
    echo export \""$var"\"=\""$(doOptionL "$(getWinVar "$var")")"\"
  else
    echo unsupported case for  >&2
  fi
done
)
fi

@huyz
Copy link

huyz commented Apr 1, 2023

@DrVanScott Thanks for that script. Have you updated your script since? You have it in a GitHub repo or even a Gist?

@zbaibg
Copy link

zbaibg commented Mar 29, 2024

I noticed in wsl2 Ubuntu 22.04.4, this problem on the PATH variable could be solved by running /mnt/c/Windows/System32/wsl.exe through ssh. Then you can open Windows program through ssh. But WSLENV variable is still missing. I am not sure where WSLENV is set to a value in nowdays version. If I open a cmd.exe from Win+R, and echo $WSLENV$$, it output nothing (Thus, if you run wsl.exe from this cmd.exe process, it cannot get WSLENV). However if I open cmd.exe from Windows Terminal (a new terminal program in new Windows version), this variable is set to some value. (Thus, if you runwsl.exe from this cmd.exe process, it can get the WSLENV)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants