VMware 虚拟机里的 Ubuntu 与 Windows 共享文件夹,是很多人用虚拟机的刚需场景。但不少同学按照网上的教程配完后,发现要么虚拟机里看不到共享文件夹,要么能看不能用,要么重启后共享就消失。我前前后后在几台不同配置的机器上配过很多次,也踩了不少坑,今天把从原理到操作的完整链路讲清楚,希望能帮你少走弯路。
1. 为什么共享文件夹值得专门研究一遍
先说说这个需求是怎么来的。我日常开发里,宿主机是 Windows,但很多编译和 Linux 环境相关的实验必须在 Ubuntu 里跑。最朴素的做法是把代码从 Windows 拷贝进虚拟机,编完再拷出来——能跑,但效率极低,尤其是遇到几十 GB 数据集、镜像文件或者频繁改动的源码目录时。
大体上有四种共享方案:共享文件夹、Samba 网络共享、拖拽复制、走 Git 等版本控制中转。
共享文件夹是 VMware 虚拟机特有的机制,它走 VMware 自己的 hgfs 协议,不需要配置 Samba 服务,也不需要知道虚拟机的 IP 地址。只要宿主机和虚拟机里装好对应的工具,再把某个 Windows 目录"挂"进虚拟机,两边就能直接读写。跟 Samba 相比,它不依赖网络配置,宿主机的防火墙对它的影响也更小;跟拖拽复制相比,它能做到文件粒度的双向实时同步,不用每次拖来拖去。
这个功能适合这些人群:
- 在 Windows 上做开发、需要在 Ubuntu 里编译验证的开发者
- 需要把大型测试数据放进虚拟机跑实验的学生或研究人员
- 通过虚拟机做跨平台软件兼容性测试、需要频繁搬数据的测试人员
- 在 Ubuntu 里处理文档、图片,想直接访问 Windows 桌面文件夹的普通用户
说白了,只要你有"频繁地、双向地、在 Windows 和 Ubuntu 之间传文件"的需求,共享文件夹就是成本最低的方案之一。
2. 共享文件夹的底层链路:hgfs 文件系统与 vmhgfs-fuse
要真正理解共享文件夹,得先知道它背后的机制。VMware 的共享文件夹并不是简单的网络磁盘映射,它靠的是 VMware 虚拟化层提供的 hgfs 协议(Host-Guest File System)。宿主机把指定目录通过 VMware 虚拟机进程暴露给客户机,客户机里再通过一个文件系统驱动,把这个远程目录挂载成本地路径。
2.1 传统挂载方式和 FUSE 方案的差异
在旧版 VMware Tools 时代,虚拟机里会加载一个内核模块vmhgfs,然后用mount -t vmhgfs .host:/ /mnt/hgfs这种方式把共享根目录挂载进来。它的特点是深度集成内核,性能不错,但问题也不少——内核升级后模块容易失配,需要重新编译或重装 VMware Tools,一旦宿主机 VMware 版本和客户机内核版本变化,整个链路就容易出问题。
后来 VMware 引入了基于 FUSE 的方案,就是vmhgfs-fuse。FUSE(Filesystem in Userspace)允许普通用户态程序来实现文件系统操作,不需要直接改内核模块。vmhgfs-fuse是一个用户态守护进程,负责与宿主机的 hgfs 服务通信,再通过 FUSE 内核接口把文件系统暴露给 Ubuntu。
用 FUSE 方案的好处很明显:
- 不容易受内核升级影响,整体稳定性更高
- 挂载权限更灵活,可以用
allow_other参数让多个用户访问 - 卸载/重挂载都更干净,不用重启虚拟机
现在从 Ubuntu 18.04 开始,官方源里的open-vm-tools默认就集成了vmhgfs-fuse,这也是我强烈推荐的方式——不需要去 VMware 官网下载 Tools 安装包,一条apt install就能搞定。
2.2 open-vm-tools 与 VMware Tools 怎么选
VMware Tools 有两套:"正牌" VMware Tools(从 VMware 菜单里 Install VMware Tools 挂载 iso 安装)和 open-vm-tools(开源版,打包在各大 Linux 发行版源里)。虽然功能上几乎一致,但 open-vm-tools 的优势非常明显——由发行版维护适配版本,跟当前内核的兼容性有保证,装起来还省去加载 iso、解压、运行安装脚本这些繁琐步骤。
对 Ubuntu 用户来说,我几乎只推荐:
sudo apt update sudo apt install open-vm-tools open-vm-tools-desktop其中open-vm-tools-desktop提供图形界面相关增强(如 X11 复制粘贴、分辨率自适应等),如果你用桌面版 Ubuntu 就一并装上;如果是纯服务器版,只装open-vm-tools即可。装上之后,共享文件夹的核心组件vmhgfs-fuse已经在其中。
2.3 挂载的本质:把 Windows 目录变成 FUSE 文件系统
理解挂载命令之前,先记住一句话:共享文件夹最终是通过 FUSE 在 Ubuntu 里"模拟"出一个本地文件系统,它的表现和真正的本地磁盘存在细微差异。比如某些文件锁语义可能不被完全支持,大规模随机读写时性能也不如本地磁盘。但这不影响绝大多数日常使用。
核心的挂载命令是:
sudo mkdir -p /mnt/hgfs sudo vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other -o uid=1000 -o gid=1000这里拆开讲一下:
.host:/表示 hgfs 的根路径,也就是宿主机共享出来的所有目录的集合/mnt/hgfs是客户机里的挂载点,目录要预先创建好,否则挂载命令会报错allow_other允许其他用户访问这个 FUSE 文件系统,不加的话只有执行挂载的用户能访问,后面会有权限坑uid=1000, gid=1000把文件的所有者映射成当前 Ubuntu 里的第一个用户,这样读写权限比较舒服
挂载完成后,在/mnt/hgfs下就能看到你在 Windows 侧共享出去的文件夹名称了。
3. 先准备 Windows 侧:创建共享文件夹并安装客户机工具
许多人卡在第一步:在 VMware 界面里加了共享文件夹,但 Ubuntu 里就是看不到。大多数情况下,问题出在客户机里缺了 hgfs 的支撑组件。所以我们先从上到下把所有准备工作做扎实,再挂载。
3.1 在 Windows 上设置共享文件夹
在 VMware 里关闭虚拟机(或者保持开机但需要后续生效),然后:
- 打开虚拟机设置,切到"选项"标签页
- 找到"共享文件夹",选择"总是启用"
- 点击"添加",选择 Windows 里的一个目录作为共享根目录,可以顺手勾选"启用此共享"
- 确认后保持"只读"或"读写"按需选择,文件传输场景选"读写"即可
一个常见误区:共享文件夹的"根目录"概念。VMware 允许添加多个共享目录,每个目录通过名字区分。在客户机里,它们会挂在同一挂载点下的不同子目录。所以如果你在 Windows 侧添加了D:\project和E:\dataset,Ubuntu 里执行完挂载命令后,会看到/mnt/hgfs/project和/mnt/hgfs/dataset两个目录。
目前 VMware Workstation Pro 在个人正式版里,共享文件夹功能默认开放,不需要额外许可证。如果你用的是较老版本,请确认工具栏里的"共享文件夹"不是灰的——灰色说明当前虚拟机配置不支持,需要检查 VM 设置里是否启用了该项。
3.2 在 Ubuntu 里安装并验证 VMware Tools 组件
接下来在 Ubuntu 里安装 open-vm-tools。前面提到过命令,这里我再强调一下操作顺序和验证方法。
先更新索引,再安装:
sudo apt update sudo apt install -y open-vm-tools open-vm-tools-desktop安装完成后,检查关键二进制是否存在:
which vmhgfs-fuse如果输出路径,说明 FUSE 版 HGFS 工具已就位;如果什么都没有,说明包没装成功,或者安装源有问题。这时要先apt update再试一次,若仍失败可检查源配置。
注意区分:Ubuntu 桌面版通常开机就通过 systemd 自动挂载 VMware 共享文件夹,路径可能是/mnt/hgfs。但我遇到的情况是,部分发行版(尤其是精简定制版或加了某些内核参数的版本)不会自动挂载,必须手动操作。所以不要依赖图形界面里"看起来没有共享文件夹"这个表象,先敲命令确认组件齐全。
3.3 确认 hgfs 模块是否加载
装完 Tools 后可以顺带检查:
lsmod | grep hgfs如果是基于内核模块的旧方案,会列出vmhgfs模块;如果走的是 FUSE 方案,vmhgfs-fuse运行时并不会要求vmhgfs模块加载。所以lsmod查不到并不代表共享文件夹不可用。
不过有个历史遗留问题:一些教程会建议加载vmhgfs内核模块,并手动创建/dev/hgfs。这个操作在新版本 open-vm-tools 里已经不需要。如果你在较旧的 Ubuntu 版本上折腾,才需要关注。
4. 在 Ubuntu 里把共享文件夹挂载起来
组件齐了,接下来才是真正的挂载实操。我在不同 Ubuntu 版本上试过,这块的排错思路基本一致。
4.1 先确认共享是否已对客户机可见
不要急着挂载。先查一下客户机是否能枚举到宿主机共享出来的目录:
vmhgfs-fuse --help这个命令能打印帮助信息,但真正作用有限。更直接的做法是挂载之后再ls。不过有个技巧:挂载时如果提示Host version 0x0 doesn't match这类错误,说明宿主机与客户机的 hgfs 版本不匹配,得同步升级 VMware(宿主机侧)和 open-vm-tools(客户机侧)。
最稳妥的排查顺序:
- Windows 侧确认共享文件夹已启用且至少有 1 个共享目录
- Ubuntu 侧确认
vmhgfs-fuse已安装 - 重新启动虚拟机,让 VMware Tools 状态刷新
我见过最诡异的一种情况:在虚拟机运行中添加了共享,但客户机上 hgfs 服务没有感知到变化,需要重启虚拟机或至少systemctl restart vmware-tools/systemctl restart vmtoolsd来刷新。优先级顺序是:先重启vmtoolsd服务,不行再重启虚拟机。
4.2 手动挂载的三种方式
手动挂载是最快验证方案,方法有三种。
第一种:传统挂载点
sudo mkdir -p /mnt/hgfs sudo vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other -o uid=1000,gid=1000挂载后立即检查:
ls /mnt/hgfs df -h /mnt/hgfs第二种:挂载到自定义目录
很多时候我不喜欢把共享放在/mnt/hgfs下,而是直接挂到工作目录,比如:
sudo mkdir -p /home/user/host_share sudo vmhgfs-fuse .host:/ /home/user/host_share -o allow_other这样访问起来路径更短,也符合"直接在家目录里干活"的习惯。
第三种:只挂载某个特定共享子目录
VMware 的 hgfs 协议支持用共享名来直接挂载。你添加共享时不是起了个名字吗?比如共享名code,那么可以这样:
sudo vmhgfs-fuse .host:/code /home/user/code -o allow_other这种挂法对"共享根目录下有多个文件夹、我只想用其中一个"的场景非常友好。不过要注意,挂载子目录时如果宿主机侧目录太多、层级太深,偶尔会碰到枚举超时的问题,遇到就把共享目录的数量精简一下。
4.3 挂载后的权限和文件所有权映射
这是最容易让人困惑的地方。Windows 目录里的文件没有 Linux 传统的rwx权限位,hgfs 会做一层映射。默认情况下,文件所有者是执行挂载命令时的用户;如果不加uid=1000,gid=1000,而你是用sudo挂载的,那么你会发现ls -l显示文件所有者是root,普通用户只能读不能写,甚至不能改。
解决方式就是挂载参数里显式指定 uid/gid。大部分桌面 Ubuntu 第一个用户 uid=1000,你可以用id -u和id -g确认:
id或者直接在挂载命令里用变量:
sudo vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other -o uid=$(id -u) -o gid=$(id -g)另外,allow_other这一步很关键。如果挂载时不加allow_other,FUSE 默认只允许挂载者访问文件系统。也就是说你sudo挂载后,普通用户访问时会得到 permission denied。加上allow_other后其他用户就能正常进目录了。
还要提醒一句:共享文件系统的权限并不完全等同于宿主机 NTFS 权限。如果某个文件原本可以访问,结果报权限错误,先查 Windows 侧该目录的 NTFS 权限,再查 Linux 侧挂载参数。两个层面缺一不可。
4.4 挂载完成后的验证工作
挂载不是"装完就跑",需要验证读写两个方向。我会在 Windows 共享目录里新建一个测试文件,到 Ubuntu 里cat;然后在 Ubuntu 里往共享目录写一个文件,回到 Windows 侧确认能看到。双向都通,这条链路才算稳。
验证可以用这些命令:
echo test > /mnt/hgfs/your_share/test_from_linux.txt cat /mnt/hgfs/your_share/test_from_linux.txt ls -l /mnt/hgfs/your_share/如果echo test报权限错误,回到 4.3 节检查 uid/gid 映射或 Windows 侧 NTFS 权限。
5. 解锁"重启后自动挂载":/etc/fstab 配置里的门道
手动挂载有个很实际的烦恼:Ubuntu 重启后,共享文件夹又消失了,每次得重复一遍sudo vmhgfs-fuse。解决办法是写入/etc/fstab,但这里的坑比想象中多。
5.1 为什么不能像普通磁盘那样配置
很多人一开始照着网上抄:
.host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other,defaults 0 0结果重启后有时正常挂载,有时挂载不了,甚至出现开机卡在"waiting for dev"的情况。原因在于 hgfs 的挂载时机依赖 VMware Tools 的用户态服务已经运行,但 systemd 在开机时并不保证vmtoolsd服务先启动完毕、再执行挂载。网络栈没就绪、内核模块没加载、fuse 设备未初始化都会导致失败。
所以我的做法是:不用defaults,而是加上nofail和x-systemd.automount。
.host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other,uid=1000,gid=1000,nofail,x-systemd.automount 0 0下面解释每个关键参数的作用:
.host:/:hgfs 的源路径,注意最后是冒号和斜杠,少了任何一个字符都挂不上fuse.vmhgfs-fuse:文件系统类型,实际对应/etc/fuse.conf里的配置,但直接写fuse.vmhgfs-fuse才能让 mount 找到正确的挂载程序nofail:如果开机时挂载失败,不要阻塞系统启动,避免卡在开机流程x-systemd.automount:让 systemd 实现按需挂载,首次访问/mnt/hgfs时才触发真正的挂载,好处是不管 vmtoolsd 是否仍在初始化,只要用户来访问,系统会等到对应服务就绪后再挂载,极大减少开机竞态问题
5.2 配置后的自检与启动顺序调整
修改完/etc/fstab后,先不要急着重启。执行:
sudo mount -a如果没有任何输出,说明 fstab 条目语法正确;再执行ls /mnt/hgfs检查是否可用。如果mount -a报错,通常是fuse.vmhgfs-fuse类型不被识别,这时要确认/sbin/mount.vmhgfs-fuse或/usr/bin/vmhgfs-fuse存在。某些系统要求先执行sudo ln -s /usr/bin/vmhgfs-fuse /sbin/mount.vmhgfs-fuse才能让 mount 按名称找到挂载程序。
另外,有些教程会建议你修改 VMware 虚拟机配置里的挂载时机,比如增加vmhgfs_allow=1这类内核参数。实际上在 open-vm-tools 下没必要,fstab 里控制好顺序和失败容忍度就够了。
5.3 fstab 配置出错导致无法进入系统的自救方法
这里必须特别提醒:fstab 写错是能搞到系统进不去的。我之前在测试机上写错过一次,开机直接停在日志界面,花了不少功夫才解决。记住自救流程:
- 重启虚拟机,在 GRUB 菜单按
e进入编辑模式 - 找到 linux 引导行末尾,加上
systemd.unit=emergency.target - 按
Ctrl+X引导进入紧急模式 - 执行
mount -o remount,rw /让根文件系统可写 - 编辑
/etc/fstab,注释掉出错的行 - 重启恢复正常
这个内容属于保命技能,你日常配置共享文件夹时不一定用得上,但如果 fstab 出了问题,能极大缩短惶恐时间。
6. 排查与避坑:我踩过的一些坑和经验
配置共享文件夹的流程并不复杂,但各种版本的排列组合(VMware 版本、Ubuntu 内核版本、桌面/服务器版)会带来一堆细节问题。这里把我在不同机器上实际遇到的问题整理成表,你可以直接对照排查。
| 现象 | 可能原因 | 处理方法 |
|---|---|---|
vmhgfs-fuse: not found | open-vm-tools 未安装或安装失败 | sudo apt install open-vm-tools |
挂载成功但/mnt/hgfs是空的 | 宿主机没有启用共享文件夹 或 共享名称与预期不一致 | 检查虚拟机设置"共享文件夹"是否"总是启用",并确认已添加至少一个共享目录 |
提示No such file or directory | 挂载点目录不存在 | sudo mkdir -p /mnt/hgfs |
| 普通用户访问共享目录提示 permission denied | 挂载时未加allow_other或未指定 uid/gid | 重新挂载,加-o allow_other -o uid=1000,gid=1000 |
| 访问细粒度文件时卡顿 | 共享文件夹跨网络文件系统语义,大目录扫描慢 | 避免共享超大目录;必要时用--加参数,或者分多个共享目录按需挂载 |
| Ubuntu 重启后共享消失 | 没有配 fstab 自动挂载 | 按第 5 节配置nofail+x-systemd.automount |
| 挂载时报版本不匹配 | 宿主 VMware 版本与客户机 open-vm-tools 版本相差过大 | 两边同步升级到较新版本 |
| 虚拟机里能挂载但不实时同步 | 需要宿主机侧的"目录变更通知"支持,FUSE 在某些场景下有缓存 | 一般重启虚拟机能解决;或挂载时尝试指定-o sync |
6.1 添加共享文件夹后 Ubuntu 里长期看不到,先重启服务
这是最高频的坑。在虚拟机开机状态下,你在 VMware 设置里添加共享文件夹,客户机不一定马上感知。建议的优先级是:
sudo systemctl restart vmtoolsd sudo systemctl restart vmware-tools注意不同发行版的服务名可能不一样。可以这样查:
systemctl list-unit-files | grep -i vmware看到相关服务后restart,再挂载。如果还不生效,直接重启虚拟机。
6.2 共享文件夹的读写性能没有想象中好
我经常听到有人期待共享文件夹能像本地磁盘一样快,实测下来差异不小。尤其是在大量小文件编译、解压场景(例如解压某个 SDK 或者跑 npm install),FUSE 加上 hgfs 协议的转发开销会显现出来。
我的经验是:源码、文档、小体积配置文件,放共享文件夹完全没问题;但遇到大数据量、大量小文件的高 IO 操作,更好的做法是把文件先复制到 Ubuntu 本地磁盘,处理完再复制回共享目录。比如用 rsync 同步:
rsync -av /mnt/hgfs/big_project/ /home/user/big_project_local/6.3 allow_other 的安全边界
allow_other虽然方便,但要注意安全边界:它允许系统上所有用户访问挂载点。在个人开发机上,这通常无所谓;但如果虚拟机里运行着多用户服务,或共享目录里有敏感数据,建议不要全局加allow_other,或者只在特定目录挂载时使用。
如果确实需要多个用户访问,可以像我们前面那样,指定uid=实际用户ID,gid=实际用户组ID,让访问者归到对应用户组即可。
6.4 不用网络也能共享,这点挺重要
很多人以为 VMware 的共享文件夹依赖虚拟网络。其实不是,hgfs 协议走的是 VMware 虚拟机 monitor 层的专属通道,即使虚拟机网络完全断开(比如把虚拟网卡禁用),共享文件夹依然可用。我在断网环境里配置过 Ubuntu,共享文件夹功能正常,这对离线迁移、封闭环境里的开发很有价值。
所以在遇到共享目录显示为空时,不要花时间去折腾网络配置,先把 VMware Tools 和虚拟机设置这两个前提排查清楚。
从实际经验来看,共享文件夹的配置链路不算长,但只要记住"宿主机启用共享目录+客户机有 vmhgfs-fuse+正确的挂载参数+开机自动挂载"这四件事,几乎所有问题都能覆盖到。我后来在新装 Ubuntu 虚拟机时,基本只用open-vm-tools加 fstab 自动挂载这一套流程,体感非常稳定。希望这篇能帮你把共享文件夹这个基础又重要的功能,一次配到位。