Is there a way to access files from one WSL 2 distro/image in another one?

I have several Unbuntu WSL 2 "installations" on my Windows 10 system and I'd like to be able to run tools like rsync and diff between them. Is it possible to mount/find where the files for these other copies exist and run Linux commands on them. I don't want to copy into that area, just be able to "copy out".

To make this more concrete I have:

X:\WSL\U18.04_1 and X:\WSL\U18.04_2

And, I can get into the 2nd one by saying:

wsl -d X:\WSL\U18.04_2 -u myname

That will bring up a bash shell in my home direction in the U18.04_2 image. Now, I would like to do effectively:

diff -rbitw /mnt/x/WSL/U18.04_1/home/myname /home/myname

But of course, that doesn't work because /mnt/x/WSL/U18.04 is not actually a filesystem (as far as I can tell).


Solution 1:

There are a few ways to accomplish this.

Option 1: /etc/fstab entries in each distro

Updated answer with the method I've been using for some time.

In each distribution, run the following command, one-time:

sudo sh -c "echo \"/ /mnt/wsl/instances/$WSL_DISTRO_NAME none defaults,bind,X-mount.mkdir 0 0\" >> /etc/fstab"

After terminating the WSL distribution and restarting (to process /etc/fstab), your distribution will be available under /mnt/wsl/<distroname> from all other WSL2 distributions.

See my related answer on Ask Ubuntu for details on why this works.

Option 2: A bind mount in /mnt/wsl

Older version of Option 1, left here for posterity. Note that this will work even if the second distribution isn't running yet. Option 1 requires that the distro be running in advance for it to be available in /mnt/wsl.

Adapted from this GitHub comment, you should be able to do:

mkdir /mnt/wsl/otherinstance
wsl.exe -d otherinstance -u root mount --bind / /mnt/wsl/otherinstance/

Honestly, this one scares me a little bit, because the "otherinstance" shuts down soon after the command is run (unless it was already running elsewhere). However, the mount seems stable, probably because (as later comments in that GitHub issue mention) all of the "drives" are available from the WSL2/Hyper-V subsystem anyway; they aren't necessarily dependent on the instance itself.

Regardless, it would be easy to allay my (probably unfounded) fears by simply running the "otherinstance" manually and performing the mount --bind from that instance itself.

Option 3: Use wsl.exe's stdin/stdout

For certain use cases, you can just use normal input/output redirection through the wsl.exe command to access a given file. For instance:

wsl.exe -d otherinstance cat ~/myfile | diff myfile -

or

diff myfile <(wsl.exe -d otherinstance cat ~/myfile) # bash (probably all posix)
diff myfile (wsl.exe -d otherinstance cat ~/myfile | psub) # fish

This is similar to how you might perform the same operations on a remote host through ssh. You can even send entire directories through the pipeline using tar (or other means).

This also does not require the second distro to be running in advance

Option 4: ssh

For the rare case, you can even set up ssh servers in each instance. The only case I've come across where I have to do this is Ansible, although rsync might be a possibility as well.

Note that setting up ssh on WSL instances isn't all that straightforward, but it's probably easier if you are only accessible it via localhost. At the least, you'll need a separate port number for each instance. I recommend reserving 22 for the Windows host itself (potentially using the Windows OpenSSH Server).

Also note that there's no concept of an init script that runs at startup in WSL, nor any Systemd equivalent. So you'll need to start the ssh server for each instance manually, or find some other method.