
1. 先想清楚共享文件夹到底解决什么问题虚拟机、Ubuntu、主机、共享文件夹这四个词凑在一起背后往往是一个非常具体的痛点代码在主机上写编译和运行在 Ubuntu 虚拟机里跑两边来回拷文件既慢又容易乱。我最早的做法是拖拽加复制粘贴小文件还行一旦是几百 MB 的数据集或者成千上万个小文件的项目目录拖拽就开始卡复制粘贴还会因为剪贴板同步的问题丢内容。共享文件夹出现的意义就是把「两个操作系统之间的文件搬运」变成「两个操作系统看同一份文件」省掉搬运这个动作本身。说白了共享文件夹是虚拟机软件提供的一层文件系统映射。主机上的一个真实目录被虚拟机软件以某种协议暴露给客户机客户机在 Linux 侧挂载成一个普通目录。你在 Ubuntu 里ls一下看到的就是主机上那个目录里的东西你在 Ubuntu 里改一个文件主机上立刻能看到。这个过程不经过网络不经过网盘也不依赖任何第三方服务纯本地映射速度取决于磁盘本身。它适合谁三类人最需要。第一类是开发人员尤其是做嵌入式、后端、编译型语言开发的Windows 主机加 Ubuntu 虚拟机的组合非常普遍代码放在共享目录里主机上用什么编辑器都行虚拟机里直接make。第二类是学生和刚入门 Linux 的朋友装完 Ubuntu 之后发现主机和虚拟机之间传个安装包都费劲共享文件夹是最省事的解法。第三类是运维和测试人员需要把一份配置或脚本快速同步到多个虚拟机里跑共享目录相当于一个轻量的分发点。这里要划清一个边界共享文件夹不是用来放数据库文件、Git 仓库、或者任何需要频繁随机读写大量小文件的场景的。原因后面会详细展开简单说就是这层映射的 I/O 语义和本地 ext4 不一样性能会有明显衰减权限模型也不是完整的 Linux 权限模型。1.1 共享文件夹、拖拽、复制粘贴三者到底差在哪很多人把这三种方式当成一回事其实它们的实现层次完全不同适用场景也完全不同。复制粘贴和拖拽依赖的是虚拟机工具的剪贴板同步和拖放功能。它本质上是「一次性传输」每次操作都是一次完整的拷贝。传输大文件时你会看到一个进度条传完之后两边各有一份独立的副本后续修改不会互相同步。而且这只在图形界面下有效你 SSH 到虚拟机里是没法拖拽的。剪贴板同步还经常出问题尤其是跨版本、跨桌面环境的时候时灵时不灵。共享文件夹是「持久映射」。设置一次只要虚拟机开着这个目录就在。它的数据始终只有一份就在主机的磁盘上。这对节省空间很有意义——你不需要在虚拟机那 60 GB 的虚拟磁盘里再放一份 20 GB 的代码和数据。网络共享SMB/CIFS、NFS是第三种方案。如果你有多台物理机或者虚拟机之间也要互访那走网络协议更合适。但如果只是主机和本机虚拟机之间绕一圈走网络协议栈反而是多余的延迟更高配置也更复杂。方式数据份数是否需要图形界面大文件表现持续同步典型用途拖拽/复制粘贴两份需要一般易中断否临时传个安装包共享文件夹一份不需要好是代码、数据集、配置SMB/NFS 网络共享一份不需要取决于网络是多机互访、跨物理机我自己的习惯是共享文件夹承担日常开发目录复制粘贴只用来传一些临时的小文件。两者不冲突各干各的活。1.2 方案选型的三个判断维度选 VMware 的共享文件夹还是 VirtualBox 的主要看你现在用的是哪个虚拟机软件没必要为了共享文件夹换软件。两者的实现机制不同配置命令也不同但思路是一致的主机侧先声明一个目录客户机侧挂载。真正需要你决定的是另外三件事。第一共享目录放在主机的哪个位置。我建议单独建一个目录比如D:\vm-share或者~/vm-share不要把整个用户目录或者某个盘符根目录共享出去。共享整个盘符的后果是虚拟机里能看到的文件数量巨大有些工具扫描目录时会非常慢而且一旦在虚拟机里误删主机上的文件是真没了。第二只读还是读写。如果只是给虚拟机提供一些参考资料、安装包、数据集勾选只读更安全。开发场景必须读写。第三要不要开机自动挂载。手工mount一次重启就失效每次开机敲一遍命令显然不现实。写进/etc/fstab是标准做法但 fstab 写错会导致系统起不来所以必须加保护参数这部分后面会详细讲。2. 动手之前必须确认的几件事配置共享文件夹踩的坑一大半不是因为命令写错了而是因为版本不匹配、工具没装全、或者共享名写错了。所以在动手之前有几项信息必须先确认清楚这几分钟的检查能省掉后面半小时的排查。2.1 确认虚拟机软件版本和工具链状态先确认虚拟机软件的版本。VMware Workstation 从 15 版本开始共享文件夹的挂载方式从老的vmhgfs换成了vmhgfs-fuse命令写法完全不同。你在网上搜到的教程如果没写版本很可能照着抄不成功。VirtualBox 这边6.x 和 7.x 在增强功能包的安装流程上也有差异7.x 对 Wayland 桌面环境的支持是逐步完善的。然后在 Ubuntu 里确认两件事。一是确认你装的是open-vm-tools还是open-vm-tools-desktop前者是命令行版本后者带图形界面集成包括剪贴板同步和自动挂载。二是确认内核模块有没有加载。VMware 路线依赖vmw_vmci、vmwgfx这些模块VirtualBox 路线依赖vboxguest、vboxsf。# 查看系统版本和内核版本 lsb_release -a uname -r # 查看 open-vm-tools 相关包的状态 dpkg -l | grep open-vm-tools # 查看 VirtualBox 增强功能模块是否加载 lsmod | grep vbox如果lsmod什么都没输出说明增强功能没装或者没加载后面无论怎么配共享文件夹都不会成功。这一步是硬性前置条件不要跳过。2.2 共享名的命名规则与目录规划共享名是主机侧给这个目录起的一个标识客户机挂载时要引用它。命名上有几个硬性约束不要用中文不要用空格不要用特殊符号。用中文名在某些版本的 VMHGFS 下会直接挂载失败或者挂上了但目录名显示为乱码。我一般用share、code、data这种全小写英文名简单可靠。主机侧的目录路径也建议用纯英文、无空格。Windows 主机上如果目录名带空格fstab 里要转义或者加引号容易出错。目录层级也不宜太深D:\vm-share\code这种就够了。另外提醒一点如果你的虚拟机做了快照共享文件夹的内容不会被包含在快照里。因为文件实际存在主机磁盘上虚拟机快照只记录虚拟磁盘的状态。这个特性有好有坏——好处是快照体积小、回滚快坏处是你无法通过回滚快照来恢复共享目录里被误删的文件共享目录的备份要靠主机侧自己的方案。提示在虚拟机设置里开启共享文件夹之后建议先重启一次虚拟机再开始配置挂载。有些版本的工具链需要重启才会重新识别新的共享配置。3. VMware 路线从主机侧设置到开机自动挂载VMware 是目前个人用户里占比最高的桌面虚拟机软件它的共享文件夹机制叫 HGFSHost Guest File System对应的客户机端工具是open-vm-tools。整条链路的思路很清晰主机侧通过设置界面声明目录客户机侧用vmhgfs-fuse挂载。3.1 主机侧的共享配置关闭虚拟机打开虚拟机设置找到「选项」标签页下的「共享文件夹」。这里有个细节如果你之前装的是旧版本 VMware可能会看到「共享文件夹」是灰色的不可点通常是因为虚拟机正在运行或者处于挂起状态必须完全关机才能修改。选择「总是启用」然后添加一条共享记录。主机路径选你规划好的目录名称填英文短名比如share勾选「启用此共享」。如果只是提供资料可以勾上「只读」。这里有个判断题主机路径的权限。如果你的主机是 Windows共享目录放在 NTFS 分区上那么 NTFS 的权限设置会直接影响虚拟机里的读写。如果发现虚拟机里能读不能写除了检查 VMware 里的「只读」勾选还要回来看主机目录的属性确认当前用户有写权限。3.2 Ubuntu 侧安装工具并验证共享名启动虚拟机先装工具。Ubuntu 官方源里的open-vm-tools比手动挂载 VMware Tools 安装镜像要省心得多推荐优先用这个。sudo apt update sudo apt install -y open-vm-tools open-vm-tools-desktop装完之后用vmware-hgfsclient验证一下这个命令会列出主机侧声明了哪些共享名。vmware-hgfsclient # 输出应该是 share 这样的共享名如果这个命令报「command not found」说明工具没装成功检查一下 apt 源或者换个镜像源重装。如果命令能执行但输出为空说明主机侧的共享没配置好或者虚拟机需要重启才能识别回去检查 3.1 的步骤。3.3 手工挂载验证顺便理解参数含义验证通过之后先手工挂载一次别急着写 fstab。手工挂载的好处是报错信息直接打屏你能立刻看到问题所在。# 创建挂载点目录名建议和共享名一致方便记忆 sudo mkdir -p /mnt/hgfs/share # 新版 VMware 使用 vmhgfs-fuse 挂载 sudo vmhgfs-fuse .host:/share /mnt/hgfs/share -o subtypevmhgfs-fuse,allow_other,uid1000,gid1000 # 验证 ls /mnt/hgfs/share这里几个参数值得解释一下理解了才能知道自己为什么这么写。.host:/share是设备名.host:代表主机这一侧/share是共享名。这个写法是 HGFS 的约定不要写成主机上的真实路径。allow_other允许除挂载者之外的其他用户访问这个挂载点。不加这个参数普通用户进不去这个目录只能 root 用日常开发非常别扭。uid1000,gid1000是强制指定挂载后文件的所有者和组。HGFS 本身不完整支持 Linux 的权限模型文件的所有者是谁往往由挂载参数决定。用id命令确认自己的 UIDUbuntu 上默认第一个用户就是 1000。指定这个参数之后你在虚拟机里就是这些文件的「主人」读写和删除都不会再报权限错误。注意allow_other需要 FUSE 允许如果报fuse: device not found或者权限相关错误检查/etc/fuse.conf里的user_allow_other是否被注释掉了取消注释即可。3.4 写进 fstab 实现开机自动挂载手工挂载验证没问题之后就可以写 fstab 了。这是配置的最后一公里也是最容易翻车的地方。fstab 语法出错会导致系统启动时卡在紧急模式所以务必加nofail。# 先备份原始 fstab养成习惯 sudo cp /etc/fstab /etc/fstab.bak # 编辑 sudo nano /etc/fstab在文件末尾追加一行.host:/share /mnt/hgfs/share fuse.vmhgfs-fuse allow_other,uid1000,gid1000,nofail,defaults 0 0几个关键点说明一下。文件系统类型写fuse.vmhgfs-fuse这是让系统在挂载时调用对应的 FUSE 挂载程序。nofail保证即使挂载失败也不会阻塞启动最多是共享目录不可用系统照常进桌面。0 0两个字段分别表示不备份、不检查FUSE 文件系统必须这么写否则fsck会报错。写完执行一次sudo mount -a测试。如果没有报错再df -h | grep hgfs看看挂载是否生效。确认之后再重启验证。重启后挂载点依然是空的那就回到排查章节八成是挂载顺序问题。4. VirtualBox 路线vboxsf 用户组是绕不开的坎VirtualBox 的共享文件夹机制和 VMware 类似但权限模型上有个非常典型的设计vboxsf用户组。不把用户加进这个组你在共享目录里就是个「外人」什么都做不了。这也是搜索「虚拟机共享文件夹权限不够」时最常见的答案。4.1 安装增强功能包VirtualBox 的共享文件夹依赖「增强功能包」Guest Additions。安装方式有两种一种是直接在菜单里点「设备 - 安装增强功能」它会把一个 ISO 挂载到虚拟机里另一种是用 Ubuntu 源里的virtualbox-guest-utils。我推荐后者省去了编译内核模块的麻烦尤其是内核升级之后源里的包会自动跟着更新。sudo apt update sudo apt install -y virtualbox-guest-utils virtualbox-guest-dkms装完之后重启一次虚拟机让内核模块加载。lsmod | grep vboxsf # 有输出说明模块加载成功如果模块没加载尝试sudo modprobe vboxsf手动加载同时用dmesg | tail看看有没有报错。常见的原因是内核版本和 DKMS 模块不匹配这时候需要升级虚拟机软件本身。4.2 vboxsf 用户组的正确加入方式VirtualBox 默认会在/media/下自动挂载共享目录目录名是sf_加上你的共享名比如共享名是share挂载点就是/media/sf_share。这个目录的所有者是 root组是vboxsf。于是问题来了普通用户默认不在vboxsf组里打开这个目录会提示权限不足。# 把自己加入 vboxsf 组 sudo usermod -aG vboxsf $USER # 查看是否加入成功 groups $USER-aG的a是关键代表追加。如果漏掉a原来的附加组会被清空可能导致你的用户失去 sudo 权限那就麻烦了。加入组之后必须注销重新登录或者直接重启才生效。很多人加完组发现还是没权限就是忘了这一步。组信息在用户登录会话建立时就确定了改完之后不重新登录不会刷新。4.3 手工挂载与 fstab 自动挂载如果不想用/media/sf_xxx这个默认位置想挂到自己的目录可以手工挂载。sudo mkdir -p /mnt/share sudo mount -t vboxsf share /mnt/share注意这里的参数顺序share是共享名/mnt/share是挂载点别写反。自动挂载有两种做法。第一种是直接用 VirtualBox 界面里的自动挂载功能它会在开机时自动挂到/media/sf_xxx简单但位置不可控而且偶尔会有挂载时机太早导致失败的情况。第二种是写 fstab位置可控但同样要小心。share /mnt/share vboxsf defaults,uid1000,gid1000,nofail 0 0VirtualBox 这边的权限处理有个细节如果你已经把自己加进了vboxsf组其实不写uid/gid也能正常读写。但写上更保险尤其是当你希望文件所有者信息明确的时候。另外 VirtualBox 的共享文件夹在只读模式下uid/gid参数会被忽略因为本来就是只读。提示VirtualBox 有个「固定分配」的选项勾上之后这个共享会在每次启动时自动挂载相当于虚拟机软件层面帮你做了 fstab 的事。如果你不想碰 fstab用这个选项更稳妥。5. 排查手册共享文件夹各种不听话的情况共享文件夹这个功能配置本身不难难的是出错之后没有明确的报错提示。挂载点空的、权限不对、重启失效这几种情况占了绝大多数。下面把典型问题和排查思路整理成速查表再逐个展开。现象最可能的原因排查命令处理方式/mnt/hgfs目录为空工具未安装或模块未加载lsmod | grep vmw安装 open-vm-tools 并重启unknown filesystem type用了旧版 mount 语法vmware-hgfsclient改用 vmhgfs-fuse重启后挂载失效fstab 语法错误或挂载顺序sudo mount -a加 nofail改用 automount权限不足只读未加入 vboxsf 组groups $USERusermod -aG 后重新登录无法 chmodHGFS 不支持完整权限模型—用挂载参数 uid/gid 控制复制粘贴也失效桌面版工具未安装dpkg -l | grep desktop安装 open-vm-tools-desktop中文文件名乱码编码不一致locale检查主机文件名与 locale 设置5.1 挂载后重启失效的深层原因这个问题问的人最多。根本原因通常是挂载顺序fstab 在处理到你的共享挂载这一行时open-vm-tools的服务还没启动HGFS 模块还没就绪于是挂载失败。加了nofail之后系统能正常启动但挂载点就是空的。解决思路有两条。一是在 fstab 里加x-systemd.automount让 systemd 在第一次访问这个目录时才执行挂载这时候系统早就启动完了模块肯定就绪。.host:/share /mnt/hgfs/share fuse.vmhgfs-fuse allow_other,uid1000,gid1000,nofail,x-systemd.automount 0 0二是配置 systemd 的依赖关系让挂载单元在open-vm-tools.service之后执行。这个方案更规范但配置量稍大需要写 override 文件。日常使用第一种就够了。如果你是想挂载 Windows 主机上的网络共享CIFS重启失效的原因则完全不同——那是_netdev参数和网络就绪时机的问题需要在 fstab 里加_netdev并确保network-online.target生效。这两种情况不要混淆。5.2 权限问题的三种典型表现第一种只能读不能写。先检查虚拟机软件里的共享设置有没有勾只读再检查主机目录本身的权限。Windows 主机上还要看共享设置里的「共享」和「安全」两个标签页的权限有没有配全。第二种能写但文件所有者是 root导致其他程序无法访问。这是 HGFS 和 vboxsf 都不完整支持 Linux 权限模型导致的解决办法就是挂载时用uid1000,gid1000强制指定所有者。这两个参数是「假权限」它不改变主机上的真实权限只是让 Linux 侧看到的属主看起来对。第三种在共享目录里创建符号链接失败。原因是 Windows 的 NTFS 不支持 Linux 风格的符号链接HGFS 映射过去之后就创建不了。绕过方法是在 Ubuntu 的本地磁盘上建一个目录在里面创建指向共享目录的符号链接而不是反过来。# 正确做法在本地目录建链接指向共享目录 mkdir -p ~/work ln -s /mnt/hgfs/share/project ~/work/project # 而不是在共享目录里建链接那样会失败5.3 复制粘贴和拖拽一起失灵的关联性这三种功能都依赖同一个东西虚拟机工具包的桌面组件。所以它们经常一起出问题。VMware 这边如果只有open-vm-tools没有open-vm-tools-desktop剪贴板同步和拖拽就是用不了但共享文件夹是好的。因为共享文件夹依赖的是内核模块不依赖桌面组件。装的时候别漏了desktop这个包。VirtualBox 这边7.x 版本在 Wayland 会话下拖拽功能一直不太稳定这是已知情况。如果你用 Ubuntu 的默认 GNOME 加 Wayland拖拽失灵时可以尝试切换到 Xorg 会话登录在登录界面点齿轮图标就能选。还有一个容易忽略的点双向复制粘贴是有开关的。虚拟机软件的「设置 - 选项 - 客户机隔离」里有「启用拖放」和「启用复制粘贴」两个勾选框默认可能是关闭的。配置共享文件夹的时候顺手检查一下这里。6. 把它用顺手几个实战习惯和取舍配置能跑通只是第一步真正影响效率的是怎么用。这块分享几个我自己踩坑之后形成的习惯都是些不起眼但很省事的细节。6.1 目录结构的分层策略我习惯在主机侧共享目录下再分一层code放代码data放数据集tmp放临时文件。虚拟机里对这三个目录的挂载方式不一样。code和data是读写挂载长期存在tmp我有时会干脆不做共享直接在虚拟机本地磁盘上跑因为编译过程的中间文件读写非常频繁放在共享目录里会明显拖慢编译速度。这里有个经验数据在一个 medium 规模的 C 项目上把源码放在共享目录里编译相比放在虚拟机本地磁盘整体编译时间大概会多出三到五成。原因不难理解HGFS 和 vboxsf 都是通过一层中间层做文件操作每次stat、open、write调用都要经过额外的转换而编译过程会产生大量小文件操作这种开销被放大了。所以我的建议是源码放共享目录方便主机编辑但如果编译速度实在受不了可以在虚拟机里建一个构建目录用 rsync 或者cp -a把源码同步过去编译。这不是共享文件夹没配好而是这类文件系统的固有特性。6.2 让编辑器在主机侧让运行环境在虚拟机侧这是我个人最推荐的用法。主机的编辑器体验好字体渲染、插件生态、快捷键都顺手虚拟机的 Linux 环境干净依赖装上就能跑。共享文件夹把两边粘起来之后工作流就变成主机上敲代码保存虚拟机里终端回车执行。进一步的做法是在虚拟机里开 SSH 服务然后用主机的终端工具连上去。这样你在主机上可以用一个窗口编辑、另一个窗口执行完全不用切虚拟机窗口。VS Code 的远程开发功能就是干这个的配合共享文件夹或者直接访问虚拟机文件系统体验很流畅。# 虚拟机里安装 SSH 服务 sudo apt install -y openssh-server sudo systemctl enable --now ssh # 查看虚拟机 IP ip addr show | grep inet虚拟机网络建议用 NAT 加端口转发或者桥接模式。桥接模式下虚拟机会拿到和主机同网段的地址主机直接连过去最方便。6.3 备份和快照的边界意识最后强调一个容易被忽视的点共享文件夹里的内容不在虚拟机快照的保护范围内。快照只记录虚拟磁盘的状态共享文件夹指向的是主机真实目录你回滚快照那部分文件不会跟着回滚。这个特性意味着两件事。一是不要图省事把重要数据只放在共享目录里主机侧的备份不能省。二是如果你需要「实验性修改」的保护比如想测试一段配置改坏了怎么办那应该把文件复制到虚拟机本地磁盘上再改改坏了删除重来或者回滚快照而不是在共享目录里直接改。反过来利用这个特性也有好处你可以把虚拟机搞得很「脏」装一堆工具、改一堆配置需要重置的时候直接删掉虚拟机重建反正代码和数据都在主机的共享目录里一点不丢。这种「虚拟机可抛弃、数据持久化」的思路是共享文件夹带来的最大价值之一。我自己这几年在 Windows 主机加 Ubuntu 虚拟机的组合上做了很多次环境重建从 18.04 到 22.04 再到 24.04每次都是删掉旧虚拟机、装新的、配一遍共享文件夹、代码目录一挂就能继续干活。配置命令我都留在一个笔记文件里复制粘贴执行十分钟搞定。这个流程跑顺了之后虚拟机就不再是「要小心维护的东西」而是一个随时可以重来的工具。如果你的共享文件夹还没配起来花这半小时值得以后每次重建环境都会感谢自己。