前言
WSL ( Windows Subsystem for Linux ) 通过/mnt
目录下的c
、d
、e
等目录可分别访问本地的C、D、E等盘,虽然可以直接访问 Windows 下的文件内容,但输入ls -al
查看文件你会发现文件权限全都是777
。这会导致一些问题出现,比如 Git 会保留这些文件的执行权限,如果你之前在 Windows 下使用过 Git Bash ,那么在 WSL 中使用git status
查看本地仓库的文件状态时你会发现它们全部被标记成了modified
。
分析问题
首先要了解 WSL 中的两种文件系统:
- VolFs
着力于在 Windows 文件系统上提供完整的 Linux 文件系统特性,通过各种手段实现了对 Inodes、Directory entries、File objects、File descriptors、Special file types 的支持。比如为了支持 Windows 上没有的 Inodes,VolFs 会把文件权限等信息保存在文件的 NTFS Extended Attributes 中。
WSL 中的
/
使用的就是 VolFs 文件系统。 - DrvFs
着力于提供与 Windows 文件系统的互操作性。与 VolFs 不同,为了提供最大的互操作性,DrvFs 不会在文件的 NTFS Extended Attributes 中储存附加信息,而是从 Windows 的文件权限(Access Control Lists,就是你右键文件 > 属性 > 安全选项卡中的那些权限配置)推断出该文件对应的的 Linux 文件权限。
所有 Windows 盘符挂载至 WSL 下的
/mnt
时都是使用的 DrvFs 文件系统。
简单来说就是 WSL 对/
目录下的文件拥有完整的控制权,而/mnt
目录中的文件无法被 WSL 完全控制(可修改数据,无法真实的修改权限)。WSL 对/mnt
目录中权限的修改不会直接记录到文件本身,而在 Windows 下对文件权限的修改直接可作用到 WSL 。关于权限在微软开发者博客中有更详细的说明。
解决方案
这只是让文件在 WSL 中的权限看起来正常(目录755
,文件644
),实际并不会作用到 Windows 文件系统下的文件本身。
在/etc/wsl.conf
中添加以下配置:
[automount]
enabled = true
root = /mnt/
options = "metadata,umask=22,fmask=111"
mountFsTab = true
由于enabled
、root
、mountFsTab
均为默认值,可以对其进行精简:
[automount]
options = "metadata,umask=22,fmask=111"
上面的方法对所有盘符都有效,如果你想在 WSL 中调用 Windows 下的应用程序(比如explorer.exe .
调用资源管理器打开当前路径)就需要对C盘进行单独设置,否则会提示没有权限。首先确认wsl.conf
中的mountFsTab
没有被设置为false
,然后编辑/etc/fstab
,添加如下内容:
C:\ /mnt/c drvfs rw,noatime,uid=1000,gid=1000,metadata,umask=22,fmask=11 0 0
此时以为所有问题都解决了,但用mkdir
命令新建一个目录,会发现新建的目录权限依然是777
。
目前民间解决方案是在.profile
、.bashrc
、.zshrc
或者其他 shell 配置文件中添加如下命令,重新设置 umask
# Fixing Bad Default Permissions
if [ "$(umask)" = "000" ]; then
umask 022
fi
未来官方解决方案是在/etc/wsl.conf
添加以下配置:
[filesystem]
umask = 022
在未来某个版本的系统更新后生效,与上面的方案理论上不会冲突,所以添加无副作用。
参考文章
Fix Windows Subsystem for Linux (WSL) File Permissions
本文作者:P3TERX
本文链接:https://p3terx.com/archives/problems-and-solutions-encountered-in-wsl-use-2.html
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。非商业转载及引用请注明出处(作者、原文链接),商业转载请联系作者获得授权。
感谢!刚试了下,WSL2 现在的版本已经解决了文件权限问题,mkdir 也不是 777 了。
感谢博主,很有用,改完之后需要重启一下电脑