Scripting with WSL interoperability: Tips & Tricks---
date: Feb 24, 2021
This is the resource page for things I have talked about or not talked about on the session Scripting with WSL interoperability: Tips & Tricks.
You can get the ppt here: https://cdn.patrickwu.space/wslconf/wslconf-wsl-interop.pptx.
You can find the source code here: https://github.com/patrick330602/wslconf.
|1607||1703||1709||1803, 1809||1903, 1909||2004|
*1: Kept for backward compatibility
*2: feature of the function extended in these builds
grep ^enabled /proc/sys/fs/binfmt_misc/WSLInterop will print
enabled if WSL interoperability is enabled, otherwise it will be a empty output.
Also, you can use the file
/proc/sys/fs/binfmt_misc/WSLInterop to check whether the script/program is running in WSL or Linux.
You can find reference for the
To get the mount location, you can use
root in option in
[automount] section to get the location. By default, it will use
/mnt/, and the logic can be something like this:
If /etc/wsl.conf exists and if root under [automount] is defined
After finding the mount location, you can scan through the already mounted drive to find where the Windows install location is, as %SystemRoot% is sometimes not defined properly.
For already mounted drive in mount location
It is suggested to running them using the full path in case the Windows Path does not append properly on the Windows side.
- straight forward and fast
- Possibly problematic with UNC path(which includes WSL file access, which locates at
\\wsl$\DistroName)but no error will possibly going to be shown.
Commands can be executed using
cmd.exe /C “Command”.
cmd.exescript support (such as
- Run under Windows environment, easier to pass environment variables
UNC path is not supported and an error will be shown as the following one when executing:
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported. Defaulting to Windows directory.
To solve this, you can just move to a Windows folder in WSL before executing the command, for example, your C Drive (
- Allows you to execute
powershellcommands and scripts
- Windows PowerShell is suggested not PowerShell Core for Maximum compatibility
Execute commands/scripts using
powershell.exe -NoProfile -NonInteractive -Command "<Command>" for faster speed.
-ExecutionPolicy ByPass if you want to execute the command.
For the raster font problem, you can refer to my article here to fix the problem.
These three options have some speed difference.
Running individual tools directly are usually the fastest; and then the
powershell.exe is slowest. Here is a benchmark video:
This is the legacy of the origin of WSL (Bash on Ubuntu on Windows).
bash.exe will start a bash login shell of your default WSL Linux distribution.
bash.exe uses the Linux bash command-line arguments, and just like linux bash, you need to execute a command like the following:
bash.exe -c "<COMMAND>"
Merged feature from
wsl.exe is the one that allows you to run and manage WSL distros. It also has allows you to run WSL with different distro with different users:
wsl [-d <distro>] [-u <user>] [-e] <Command>:
-e is the interesting part here:
wsl.exeexecutes commands with the default login shell of your WSL distribution.
wsl.exe -eexecutes commands on your WSL distribution without any shell.
<distro>.exe allows you to interact with a specific distro. However, it has some interesting behaviors that you need to pay attention:
<distro>.exewith no arguments launches the user’s default shell in the user’s home directory;
<distro>.exe runlaunches the user’s default shell in the current working directory;
<distro>.exe run [Command]run the provided command line in the current working directory with user’s default shell.
But there are some issues:
- Imported distributions don’t have
.exe can be different from distribution registered name.
I am not able to cover everything in WSLConf, so here are some additional tips and tricks you might be interested in:
I have posted a post about this topic before. You can view it here.
The section is moved to this post for better visibility.
You can start using the
Start-Process command in powershell, which will become something like the following:
powershell.exe -NonInteractive -NoProfile -Command "Start-Process -FilePath powershell.exe -WorkingDirectory \"$(wslpath -w $(pwd))\" -ArgumentList "-NonInteractive -NoProfile -Command <Command>" -Verb RunAs"
You might also want to tweak the line for your needs.
If you find this is a bit too long or it is a bit complicated, you can use the following script from scoop creator Luke Sampson to do the thing: https://github.com/lukesampson/psutils/blob/master/sudo.ps1. To use this one,
-ExecutionPolicy ByPass is suggested to use.