You're going to run into a couple of things here.
PATH
differences
First, and what you are running into at the moment, is the difference in $PATH
. When you run WSL directly on the host in the terminal, it starts your shell in a fairly "unorthodox" way. At least, it's quite different than if you were running on a normal Linux host.
"Normally", you'd see something like login
called to authenticate your user. login
(and ssh
) uses PAM, the Plugable Authentication Module system to define what happens during the authentication process. One of the commonly configured modules is pam_env, which can change the environment.
You can see this defined in WSL/Ubuntu in /etc/pam.d/login
and /etc/pam.d/sshd
. Both include the line:
session required pam_env.so
You'll see in the man page that pam_env
processes /etc/environment
, and on Ubuntu 20.04 on WSL, that's defined as:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
That's the PATH
you should see when ssh
'ing in to your WSL instance, plus any changes made in your shell startup files.
On the other hand, you may have noticed that WSL doesn't actually require a login when you launch it locally. Since it's running at the same permissions as your Windows account, and you're already logged into Windows, there's really no point in additional authentication here. This is true no matter what WSL user you use.
WSL launches your shell using /init
, it's PID1 init process. /init
is responsible for setting up the tight Windows integration, including (among other things):
- Appending your Windows path to your WSL/Linux
PATH
- Setting up the Interop files needed that allow you to start Windows
.exe
cutables under WSL/Linux.
In case it's not clear, this is why code
isn't found when you login via ssh
. Since VSCode is a Windows executable, and in your Windows path, it's only there (by default) when that path is specifically added by /init
. It is not there in the /etc/environment
PATH
used by sshd
.
Remote GUI's in Windows
But really, even adding it to the path won't help much here.
I'm not sure of your exact use-case for trying to run VSCode through SSH, but note that running Windows GUI applications through SSH is quite a bit different than X forwarding on Linux. There's really not a one-to-one equivalent.
By default, even if you provide the full path of the Windows executable, it will not execute through SSH. This is to be expected. Even the Windows OpenSSH server has issues with this since it runs as a service, and services do not have GUI access. See this question for some more information there.
I'm not sure if there's a way to get the GUI to display on the remote host through WSL. I think it's unlikely, and probably not worthwhile regardless.
The best scenario I could see would be to use Windows OpenSSH running as a normal user, as documented in that previous question. Then, once logged into your Windows user, run wsl
there. Then, you might be able to launch a GUI client on the SSH host itself.
Remote VSCode
What you probably want to do is access your WSL instance through VSCode remotely in the first place.
There are at least three supported solutions for that:
Remote Desktop Protocol
Assuming you have Windows Pro or higher, you can easily access your host desktop, including WSL and VSCode, from any client that supports RDP.
VSCode's "Remote - SSH" extension
Installing the "Remote - SSH" extension, or the "Remote Development" extension pack, will allow you to directly open any SSH instance from within VSCode, including browsing the filesystem and debugging. It works the same way that you've seen with WSL, where it sets up a server inside your Linux instance that it then communicates with over SSH.
Run the Linux version of VSCode and forward it to the ssh client
This is probably my least favorite option, just because the other two are much better, but you can always install the Linux version of VSCode into WSL/Ubuntu, SSH in remotely, and forward the X client to an X host running on the same machine as your SSH client.
Of course, if the machine that you are SSH'ing from is a Windows host, you'll still need an X server. On Windows 10, you'll need a third-party X server, but on Windows 11 you could use WSLg for this.
And, of course, this solution isn't limited to VSCode. Any Linux editor or IDE could be used in this way.