As ps4080
's answer mentions, the right way to do this is wsl -e -- <command>
(or, typically wsl -e <command>
).
However, there are actually quite a few nuances you might run into with this technique, and it's nice to understand what's going on with each exact incantation so you can use the right one when needed:
wsl <command>
- Runs the default shell for the current user
- ... as a non-login, non-interactive shell
- ... in the directory passed in by the owning Windows process
- Runs
<command>
in that shell
Depending on your shell, you can see this with wsl ps -eH
:
PID TTY TIME CMD
1 ? 00:00:00 init
18 ? 00:00:00 init
19 ? 00:00:00 init
20 pts/0 00:00:00 fish
28 pts/0 00:00:00 ps
Note that it's difficult to see this when bash
is your default shell since -c
results in an implicit exec
.
The fact that this runs in the directory of the owning Windows process can be handy, since you can do:
wsl ls -lh
... in PowerShell to get "human readable" file sizes, something that is surprisingly difficult to do otherwise.
The trickiest part of this is that second qualifier. WSL runs your shell as a non-login, non-interactive shell when started this way. This means that ~/.bashrc
and ~/.bash_profile
are not sourced on startup. This can cause confusion when attempting to run a command that requires something to be done in the startup files (e.g. setting an environment variable).
wsl -e <command>
- Runs
<command>
as the shell
- ... in the directory passed in by the owning process
The -e
bypasses your default shell entirely.
> wsl ps -eH
PID TTY TIME CMD
1 ? 00:00:00 init
7 ? 00:00:00 init
8 ? 00:00:00 init
9 pts/0 00:00:00 ps
This can be slightly more efficient since you avoid the startup overhead of the shell, but it's typically not worth worrying about.
wsl -e bash -lic <command>
- Runs
bash
as your shell (regardless of whether it is the default shell or not)
- Forces it to be a login, interactive shell (
-li
) so that ~/.bashrc
and ~/.bash_profile
(and/or others) are sourced
- ... in the directory passed in by the owning Windows process
- Runs
<command>
in that shell
This is the version to use if the command needs anything from your startup configuration.