有没有办法在一个 WSL 2 发行版/映像中访问另一个 WSL 2 发行版/映像中的文件?

有没有办法在一个 WSL 2 发行版/映像中访问另一个 WSL 2 发行版/映像中的文件?

我的 Windows 10 系统上有几个 Unbuntu WSL 2“安装”,我希望能够在它们之间运行 rsync 和 diff 等工具。是否可以挂载/查找这些其他副本的文件所在的位置并在它们上运行 Linux 命令。我不想复制到那个区域,只想“复制出来”。

为了使这一点更加具体,我有:

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

而且,我可以通过以下方式进入第二个:

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

这将在 U18.04_2 映像中的我的主目录中打开一个 bash shell。现在,我想有效地执行以下操作:

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

但当然,这是行不通的,因为 /mnt/x/WSL/U18.04 实际上不是一个文件系统(据我所知)。

答案1

有几种方法可以实现这一点。

选项 1: /etc/fstab每个发行版中的条目

已更新,用我个人已经使用了一段时间的方法回答。

在每个发行版中,运行以下命令一次:

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

1(感谢@mtraceur 的评论/建议和随后的编辑命令。简化引用始终是一个受欢迎的变化!)

终止 WSL 发行版并重新启动(以处理)后,您的发行版将在所有其他 WSL2 发行版/etc/fstab下可用。/mnt/wsl/instances/<distroname>

2如果此方法无效,请参阅选项 1.5

看看我的Ask Ubuntu 上的相关答案了解其工作原理的详细信息。

选项 1.5: /etc/fstab针对最新 WSL 版本的解决方法

在最近的 WSL 版本(我相信是 0.47.1 及更高版本)下,时间问题/更改意味着在挂载(tmpfs 文件系统)fstab之前处理和挂载/mnt/wsl。如果您使用的是最新的 WSL 版本,并且发现/mnt/wsl/不包含instances子目录,则:

sudo -e /etc/wsl.conf

并添加以下内容:

[automount]
mountFsTab = false

[boot]
command = sleep 5; mount -a

这应该等待足够长的时间才能进行处理,/etc/fstab以允许/mnt/wsl首先由 WSL 安装。

如果您使用的是 Systemd,您也可以创建一个.mount文件来解决该问题。请参阅@SteveMeierhofer 的回答了解详情。

选项 2:使用 的wsl.exestdin/stdout

(福利1:此方法也适用于 WSL1)
(优点2:无需提前配置)
(奖励#3:即使第二个发行版尚未运行,它也能工作。选项 1 要求发行版提前运行才能使用/mnt/wsl。)

对于某些用例,您只需通过命令使用常规输入/输出重定向即可wsl.exe访问给定文件。例如:

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

或者

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

这类似于通过 在远程主机上执行相同操作的方式。您甚至可以使用(或其他方式)ssh通过管道发送整个目录。tar

这也不需要提前运行第二个发行版

选项 3:ssh

在极少数情况下,你甚至可以在每个实例中设置 ssh 服务器。我遇到的唯一一个情况是做到这一点是 Ansible,尽管rsync也可能是一种可能性。

请注意,在 WSL 实例上进行设置ssh并不是那么简单,但如果您仅通过 localhost 访问它,则可能会更容易。至少,您需要为每个实例设置一个单独的端口号。我建议为 Windows 主机本身保留 22(可能使用 Windows OpenSSH 服务器)。

选项 4:绑定安装/mnt/wsl

选项 1 的旧版本,留在这里以供后人参考。

改编自此 GitHub 评论,你应该能够做到:

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

老实说,这个让我有点害怕,因为“其他实例”在命令运行后很快就会关闭(除非它已经在其他地方运行)。但是,挂载似乎很稳定,可能是因为(正如该 GitHub 问题中后面的评论所提到的)所有“驱动器”都可以从 WSL2/Hyper-V 子系统获得;它们不一定依赖于实例本身。

mount --bind无论如何,只需手动运行“其他实例”并从该实例本身执行,就可以轻松消除我的(可能毫无根据的)担忧。

答案2

如果你有来自Microsoft Store然后就可以使用 Systemd 了。一旦 WSL 实例运行 Systemd,请创建一个挂载文件,例如:

/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

然后启用挂载:

sudo systemctl daemon-reload

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

所有 WSL 文件均可在 处获取/mnt/wsl/instances

答案3

最简单的方法:是 Windows 资源管理器。

  1. 打开 Windows 资源管理器并访问“远程”地址\\wsl$,您将看到类似以下内容: 示例结果
  2. 现在右键单击其中一个并选择“在新窗口中打开”
  3. 将它们并排放置并根据需要浏览/复制/粘贴文件。

答案4

根据 Steve 的回答,我将其包装成一个一体化命令,您可以将其粘贴到所有要链接文件系统的 WSL 发行版中。它还包括对带有破折号的发行版(例如 Ubuntu 发行版)的修复。

这已在 Ubuntu 20.04 和 24.04 上进行了测试,并且都启用了 systemd。

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

相关内容