18

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).

7
  • Simple solution would require OpenSSH; Complicated solution but probably the most elegant solution you can hope for.
    – Ramhound
    Commented Jun 26, 2021 at 22:37
  • Ok, explain in a little more detail. How do I SSH from one distro to another? How do I give them IP addresses, etc. Commented Jun 26, 2021 at 23:10
  • They should already have an IP address. You would simply install OpenSSH like any other Linux installation
    – Ramhound
    Commented Jun 27, 2021 at 0:23
  • They both have the same IP addresses. So, that's not going to help. I need a way to find the Linux name of the filesystem. The Linux equivalent of "\\wsl$\U18.04_1". Commented Jun 27, 2021 at 8:06
  • Why don’t you assign different IP addresses?
    – Ramhound
    Commented Jun 27, 2021 at 17:04

5 Answers 5

25

There are a few ways to accomplish this.

Option 1: /etc/fstab entries in each distro

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

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

echo "/ /mnt/wsl/instances/$WSL_DISTRO_NAME none defaults,bind,X-mount.mkdir 0 0" | sudo tee -a /etc/fstab

1 (Credit and thanks to @mtraceur for the comment/suggestion and subsequent edited command. Simplified quoting is always a welcome change!)

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

2 See Option 1.5 if this doesn't work

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

Option 1.5: /etc/fstab workaround for recent WSL releases

Under recent WSL releases (0.47.1 and later, I believe), a timing issue/change means that the fstab is processed and mounted before /mnt/wsl (a tmpfs filesystem) is mounted. If you are using a recent WSL release, and you find that /mnt/wsl/ does not contain an instances subdirectory, then:

sudo -e /etc/wsl.conf

And add the following:

[automount]
mountFsTab = false

[boot]
command = sleep 5; mount -a

This should wait long enough before processing /etc/fstab to allow /mnt/wsl to be mounted by WSL first.

If you are using Systemd, you can also create a .mount file to workaround the issue. See @SteveMeierhofer's answer for details.

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

(Bonus #1: This method works on WSL1 as well)
(Bonus #2: It requires no advance configuration)
(Bonus #3: It 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.)

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 3: 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 accessing 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).

Option 4: A bind mount in /mnt/wsl

Older version of Option 1, left here for posterity.

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.

1
  • As yet another option, you may use a mount command like this. sudo mount -t none / /mnt/wsl/instances/$WSL_DISTRO_NAME -o defaults,bind,X-mount.mkdir
    – kamae
    Commented Jul 27, 2023 at 6:31
6

If you have a recent WSL release from the Microsoft Store then Systemd can be used. Once a WSL instance is running Systemd, create a mount file such as:

/etc/systemd/system/mnt-wsl-instances-${WSL_DISTRO_NAME}

[Unit]
Description=WSL Instances

[Mount]
What=/
Where=/mnt/wsl/instances/${WSL_DISTRO_NAME}
Type=none
Options=defaults,bind,X-mount.mkdir

[Install]
WantedBy=multi-user.target

And then enable the mount:

sudo systemctl daemon-reload

sudo systemctl enable mnt-wsl-instances-${WSL_DISTRO_NAME}.mount --now

All WSL files are available at /mnt/wsl/instances.

4
  • I like it -- Like I said in my answer, this should be a reliable way to get around the timing issue, so I'm really glad you took the time to document the proper configuration! Systemd mounts also (IIRC) some additional flexibility with dependency management and timing. Users can even mix-and-match, using your System configuration in distributions where they have it enabled, and the boot option I mention in others. They'll still be accessible in both directions. Great first answer! Commented Feb 9, 2023 at 4:26
  • One minor suggestion as I read through it in detail - Perhaps change the filename to just /etc/systemd/system/wsl-instance.mount -- There's really no reason to have a unique filename based on the distro_name, right? Commented Feb 9, 2023 at 4:32
  • I'm not sure if that filename will work. I'm no expert, but I think systemctl wants the name of the file to match the "where" path given in the file. Also, I couldn't have gotten this answer without your original answer -- thanks. Commented Feb 15, 2023 at 20:22
  • It seems that the file name should be /etc/systemd/system/wsl-instance-${WSL_DISTRO_NAME}.mount instead (with extension .mount). In addition, make sure there is no hypen - in WSL_DISTRO_NAME! Or an error Where= setting doesn't match unit name. Refusing. will occur (unix.stackexchange.com/a/345518/438616). One simple solution in this case is to replace all ${WSL_DISTRO_NAME} with a name without hypen.
    – sup39
    Commented Apr 17, 2023 at 1:17
3

Easiest way ever: is Windows Explorer.

  1. Open windows explorer and access the "remote" address \\wsl$, you will see something like these: example result
  2. Now right-click one of them and select "Open in a New Window"
  3. Set them side by side and explore/copy/paste files as you see fit.
1
  • 3
    Welcome to Super User! I recommend that you re-read the question, which specifically says in the first sentence, "and I'd like to be able to run tools like rsync and diff between them." Your proposal to use Windows Explorer to "explore/copy/paste files as you see fit" just doesn't appear to me to be a solution to this question. I'm fairly certain that there are other questions here on Super User to which your answer might be appropriate, but this doesn't appear to be it. Thanks! Commented Feb 9, 2023 at 4:11
1

Building on Steve's answer, I've wrapped it to be an all-in-one command that you can just paste into all WSL distros that you want to link filesystems with. It also includes the fixes for distro's that have dashes in them, e.g. Ubuntu distros.

This is tested on Ubuntu 20.04 and 24.04 with systemd enabled in both.

cat <<EOF | sudo tee /etc/systemd/system/mnt-wsl-instances-${WSL_DISTRO_NAME/-/}.mount
[Unit]
Description=WSL Instances

[Mount]
What=/
Where=/mnt/wsl/instances/${WSL_DISTRO_NAME/-/}
Type=none
Options=defaults,bind,X-mount.mkdir

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload

sudo systemctl enable mnt-wsl-instances-${WSL_DISTRO_NAME/-/}.mount --now
1
  • That worked out for me. Thank you! Except that, I cannot copy files between distros. Getting cp cannot stat .... permission denied. Adding read permission a+r recursively on the home folder did help. Commented Jun 12 at 13:42
0

You can copy files from an old WSL to a new WSL through SSH, and preserve file permissions. Ex:

Old WSL:

sudo apt install ssh
sudo vi /etc/ssh/sshd_config   =>   port 22000
sudo service ssh restart

New WSL:

# ssh localhost:22000
rsync -av -e 'ssh -p 22000' localhost:src_old_machine_file dst_new_machine_file

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .