在 WSL 2.0 上的 Ubuntu 中,方法是什么:
- 将 Windows 的 c:\lhome 挂载到 Ubuntu 的 /lhome,然后
- 将 /lhome/username (Windows c:\lhome\username) 作为用户名的主目录?
Ubuntu 中的所有程序都需要尊重用户名的主目录是 /lhome/username
答案1
正如评论中提到的,不建议将 WSL2 主目录放在 Windows 驱动器上,原因如下:
您的 Linux 主目录应位于符合 POSIX 标准的驱动器上。Linux 应用程序将期望这种情况。虽然大多数应用程序都可以,但最终您会遇到一些无法按预期运行的情况。我们可以(并且将)使用下面的 WSL 设置来缓解这种情况,但我们无法更改某些 Windows 行为。
从 WSL2 访问 Windows 驱动器是极其慢的与虚拟 ext4 文件系统相比。正如我在链接的答案中提到的那样,在 WSL2 下的 Windows 驱动器上签出 WSL2 存储库大约需要 8 分钟,但在“本机”WSL2 文件系统上只需几秒钟。
考虑到这一点,默认的 WSL2 文件系统位于虚拟 SDD(Windowsext4.vhdx
文件)中。默认情况下,该文件的位置位于:
C:\Users\<windows_username>\AppData\Local\Packages\<distro_package>\LocalState\ext4.vhdx
我们可以通过(至少)三种方式来“更改”主目录,以使其不在该位置。
选项 1:将整个 WSL 虚拟驱动器移动到新位置/发行版
我的个人偏好(而且我现在总是这样做)是将发行版本身复制到新位置。
退出 WSL
启动 PowerShell 并运行以下命令:
cd ~ wsl -l -v # Confirm the name of the distro wsl --export <distroname> wsl_backup.tar mkdir <new_disk_location> # C:\lhome perhaps # New distro name can be whatever you want, # but not Ubuntu, Ubuntu-20.04, etc. wsl --import Ubuntu_WSL2 <new_disk_location> wsl_backup.tar wsl ~ -d Ubuntu_WSL2
您将以 root 用户身份启动。您需要更改默认用户名。请参阅这个答案以获取有关如何创建或修改的信息
/etc/wsl.conf
。
一旦确认新实例正常运行,就可以使用以下命令删除旧实例:
wsl --unregister <old_distroname>
您已手动配置的发行版不会受到卸载 Ubuntu 应用程序本身的影响。
这种方法可能满足或不满足您对这种用例的特定需求,但再次强调,这是我的个人选择。
选项 2:为您的主目录创建并安装新的 vhdx(仅限 Windows 11)
笔记:我还没有在生产系统中广泛测试过这项技术(也没有测试下一项技术)。
由于您使用的是 Windows 11,因此您可以为主目录创建并挂载单独的 vhdx 文件。如果您拥有可以从 Windows 11 下的 Microsoft Store 安装的 WSL Preview,那就更容易了。
我将在这里介绍预览方法,并向您介绍如何在 WSL 中挂载 VHD 文件如果您需要走更复杂的路线。
然而,这种技术有一个很大的缺点。此时,您必须在启动 WSL 之前手动将虚拟磁盘安装到 WSL 中。我期望最终会有一个“自动安装”选项.wslconfig
,但它目前还没有,或者至少没有记录。
因此,如果 WSL 关闭或重新启动,您需要wsl --mount
在重新启动之前手动发出命令,否则将找不到您的主目录。
考虑到这一点,现在在新的虚拟磁盘上设置主目录:
一次性配置:
在一个行政PowerShell,运行:
New-VHD -Dynamic -SizeBytes 60gb -BlockSizeBytes 1mb -Path C:\lhome\userhome.vhdx
在您的常规 PowerShell 会话中:
wsl --mount --vhd --bare C:\lhome\userhome.vhdx wsl ~
在 WSL 内部:
lsblk # Identify the proper drive (likely the last one listed, but confirm) sudo mkfs -t ext4 /dev/<drive> sudo mkdir /lhome
退出 WSL,然后再次从 PowerShell(以普通用户身份)输入:
wsl --terminate <distroname> wsl --unmount C:\lhome\userhome.vhdx wsl --mount --vhd --name lhome C:\lhome\userhome.vhdx wsl ~ -u root
在 WSL 内部(根据前面的内容,您现在应该是 root 身份
-u root
),确认您/mnt/wsl/lhome
现在已经安装了。编辑
fstab
:sudo -e /etc/fstab
在底部添加以下行(制表符分隔字段):
/mnt/wsl/lhome /lhome none bind
编辑
wsl.conf
:sudo -e /etc/wsl.conf
添加以下内容:
[automount] mountFsTab = false [boot] command="mount -a"
这本质上是为了解决一个时间问题(希望如此),
wsl --mount
即直到后/etc/fstab
已处理。它会关闭自动处理,然后将其作为启动命令手动运行。这是一个 hack 解决方法,但对我来说很有效。在已安装的 vhdx 内创建新的主目录:
mkdir /lhome/username # Assuming your default uid/gid is 1000, which it should be under WSL chown 1000:1000 /lhome/username usermod -d /lhome/username yourusername
退出 WSL。在 PowerShell 中发出:
wsl --terminate <distroname> wsl ~
您的主目录现在应该是/lhome/username
。您可以使用 来确认这一点cd ~; pwd
。
同样,此方法要求您在wsl --mount
每次 WSL 本身重新启动时(通过计算机重新启动或wsl --shutdown
其他方式)发出命令。
选项 3:绑定安装到 Windows 文件夹
再次强调,由于本文开头列出的理由,确实不推荐这种方法,但还是建议使用。
假设你想C:\lhome
将 Windows 变成/lhome
WSL:
如果您尝试了上述第二个选项,请撤消所有更改。如果您尝试了选项 2,并且想要切换到选项 3,请
wsl --shutdown
在继续操作之前确保您也已完成。在管理 PowerShell 中:
mkdir C:\lhome # directory must be empty fsutil.exe file setCaseSensitiveInfo C:\lhome\ enable
这将启用区分大小写,因此
abc
和ABC
是不同的文件。这至少使我们更接近 POSIX 兼容性。在文件资源管理器中,右键单击
C:\lhome
,选择特性->安全和编辑“已验证的用户”添加“完全权限”。回到 WSL:
sudo mkdir /lhome sudo -e /etc/fstab
...并在底部添加以下行:
drvfs /lhome 9p rw,dirsync,noatime,aname=drvfs;path=C:\lhome;uid=1000;gid=1000;metadata;umask=22;fmask=11;case=dir,mmap,access=client,msize=262144,trans=virtio 0 0
C:\lhome
这将安装Windows/lhome
并启用metadata
和case=dir
改进 POSIX 兼容性。这(再次)假设您的用户是 UID/GID 1000。如果不是,请进行调整。退出 WSL,终止它(从 PowerShell --
wsl --terminate <distro_name>
)并重新启动。检查驱动器是否已安装mount | grep lhome
。创建用户主目录:
mkdir /lhome/username
确认
C:\lhome\username
现在存在。退出 WSL,然后使用以下命令重新启动
wsl ~ -u root
:# Assuming your default uid/gid is 1000, which it should be under WSL chown 1000:1000 /lhome/username usermod -d /lhome/username yourusername
当然,这模仿了上述第二种选择的步骤。
退出 WSL。在 PowerShell 中发出:
wsl --terminate <distroname> wsl ~
您的主目录现在应该是/lhome/username
。您可以使用 来确认这一点cd ~; pwd
。如果您,您也touch ~/abc
应该会在目录中找到创建的文件。C:\lhome\username