ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

虚拟机共享文件夹配置:Ubuntu+VMware挂载与排错

虚拟机共享文件夹配置:Ubuntu+VMware挂载与排错 折腾虚拟机的人基本都会撞上这道坎宿主系统里下载好的安装包、IDE 工程、数据集怎么让虚拟机里的 Ubuntu 用起来顺手复制粘贴大文件慢得让人抓狂拖拽功能时灵时不灵U 盘来回插拔更是自找麻烦。虚拟机共享文件夹这件事说穿了就是在宿主机和客户机之间架一条稳定的文件通道让你在 Windows 或 Linux 主机上改完代码切到 Ubuntu 里直接编译运行中间不需要任何手动搬运。它解决的核心问题是文件的双向可见与实时同步适合刚装完 Ubuntu 的新手也适合天天在两个系统之间来回切换的开发者。我前后在 VMware Workstation、Player 和国产化信创环境的虚拟化平台上都配过这套东西踩过的坑足够写一本小册子下面把我验证过的完整流程、参数取舍和排错思路一次讲透。1. 共享文件夹这件事先想清楚你要的是哪一种很多人一上来就问命令怎么写其实更该先问自己我到底需要多大粒度的文件互通不同的需求对应完全不同的技术路线选错了后面全是麻烦。这一步想清楚能省掉后面一半的调试时间。1.1 四种把文件搬进虚拟机的方式别选错我一般把这几种方案归成四类各有各的适用场景硬套某一种往往事倍功半。第一类是虚拟机软件自带的主机共享机制。VMware 系列叫 HGFSHost Guest File SystemVirtualBox 叫共享文件夹加 Guest Additions本质都是虚拟机监控层提供的一个虚拟文件系统驱动客户机里挂载后就能看到一个普通目录。优点是配置简单、双向读写、不依赖网络配置缺点是性能一般处理海量小文件时明显慢。第二类是网络文件共享。主机开个 SMB 或者 NFS 服务Ubuntu 端用 CIFS 或 NFS 挂载过来。这种方式的好处是完全走标准网络协议跨物理机、跨云主机都通用坏处是依赖网络连通和账号配置出问题时排查链路更长。第三类是远程传输通道。Ubuntu 里开 SSH 服务主机用 SFTP、SCP、rsync 推拉文件反过来主机开 SSHUbuntu 端用 SSHFS 挂载主机目录。这条路线我特别推荐给跨网络场景尤其是虚拟机和主机不在同一台物理设备上的情况。第四类是临时手段也就是拖拽、剪贴板复制粘贴、共享 U 盘。它们适合偶尔传一两个小文件绝对不适合当常规工作流因为超过一定体积就会失败而且失败时往往没有任何明确报错。注意拖拽和剪贴板共享依赖 open-vm-tools-desktop而且对图形会话类型敏感。如果你的 Ubuntu 用的是 Wayland 会话剪贴板互通经常抽风切换到 Xorg 会话通常能解决。1.2 我为什么默认推荐原生共享文件夹日常开发场景下我默认推荐第一种方案理由有三条。第一配置成本最低虚拟机设置里勾两下客户机里装个包五分钟能跑通。第二它不占用网络端口不需要关心主机和虚拟机的 IP 是不是同一网段NAT 模式下照样能用。第三路径稳定挂载点固定IDE 和构建脚本里写死路径也不会失效。但它有个明确的性能边界HGFS 的读写吞吐大概只有本机磁盘的三分之一到一半随机小文件操作更慢。所以我的习惯是共享目录只用来放需要频繁跨系统查看的源文件、配置文件、数据集编译输出目录、依赖缓存目录、Git 仓库的 .git 目录一定放虚拟机本地磁盘。这个原则后面还会展开讲因为它是很多诡异问题的根源。2. 主机端配置共享文件夹在哪里开要开哪几个开关主机端配置看起来最简单实际上最容易卡住新手因为 VMware 各个版本的界面入口变过好几次很多人找不到那个选项就以为是软件不支持。2.1 VMware 17 里那个找不到的选项藏在哪正确路径是先关闭虚拟机挂起状态也可以但关机最稳妥在虚拟机列表里右键目标虚拟机选择设置弹出的对话框顶部有一排标签页默认停在硬件上很多人只看这一页所以永远找不到。你需要点右边的选项标签在左侧列表里找到共享文件夹这一项。点进去之后有三个单选总是启用、在下次关机或挂起前一直启用、禁用。要开机自动挂载必须选总是启用。这三个选项的设计意图是给不同使用习惯的人留余地比如你只是临时传一次文件选第二个就够了不会在系统里留下长期挂载点。然后点下方的添加按钮会弹出一个向导。主机路径填你想共享的目录比如D:\code\project。名称建议用纯小写英文加下划线比如ws_share不要用中文和空格——中文名在部分版本的客户机驱动里会挂载失败空格则会导致 fstab 转义问题后面会细讲。勾选启用此共享如果只需要 Ubuntu 读主机文件而不需要回写可以再勾只读这样能避免误删主机文件。注意如果你用的是 VMware Workstation Player共享文件夹功能同样存在但只能在虚拟机处于关机状态时配置而且选项标签的位置和 Pro 版略有差别。2.2 命名、路径与只读开关的取舍共享名称这个细节值得单独说。它不只是显示用的标签而是客户机挂载时的标识符。在 Ubuntu 里执行vmware-hgfsclient命令列出来的就是这些名称。挂载时可以整体挂载.host:/也可以只挂某一个共享写.host:/ws_share。如果名称里带空格fstab 里必须写成ws\040share这种转义形式非常容易写错所以干脆别用空格。主机路径的选择也有讲究。放在系统盘根目录下问题不大但如果你共享的是整个用户目录客户机会看到一堆缓存文件和隐藏目录索引和遍历都会变慢。我的做法是在主机上单独建一个目录比如D:\vm_share里面再按项目分子目录共享这一个根目录就够用。这样虚拟机里只有一个挂载点管理起来干净。只读开关我的建议是数据类目录默认开只读代码类目录保持读写。原因是共享目录的删除操作在客户机里执行时是真正落到主机磁盘的没有回收站兜底。写过一次rm -rf到共享目录的人都会记住这个教训。3. 虚拟机端准备open-vm-tools 装对版本才有 /mnt/hgfs主机配置完了Ubuntu 这边如果什么都不装/mnt/hgfs 目录是空的甚至目录本身都不存在。这时需要的是 open-vm-tools 这套开源工具集。3.1 一条命令装齐桌面版和服务器版的差别Ubuntu 从 14.04 之后就不再推荐安装 VMware 官方提供的旧版工具包而是用发行版仓库里的 open-vm-tools。命令很简单sudo apt update sudo apt install -y open-vm-tools open-vm-tools-desktop这两个包的分工要搞清楚。open-vm-tools是核心提供 HGFS 驱动、时间同步、内存气球回收等基础能力服务器版 Ubuntu 装它就行。open-vm-tools-desktop是桌面增强包提供剪贴板共享、分辨率自适应、拖拽文件能力只在带图形界面的系统上需要。如果你装的是 Ubuntu Server硬装 desktop 包会连带拉一批图形库白白占空间。装完之后建议重启一次因为 HGFS 是内核模块虽然可以手动 modprobe但重启能顺带让桌面增强组件全部生效省去判断哪些服务没起来的麻烦。有个细节很多人忽略如果你的 Ubuntu 是最小化安装可能缺少 fuse 相关依赖挂载时会提示找不到fuse.vmhgfs-fuse这个类型。这时候补一条sudo apt install -y fuse3fuse 是什么可以类比成把用户态程序伪装成内核文件系统的中间层。vmhgfs-fuse 就是这么一个用户态程序它通过 FUSE 接口把自己挂载成目录所以你看到的共享目录实际上是 vmtoolsd 在后台帮你搬运数据。3.2 装完先自检三个命令确认链路通不通在动手挂载之前先把这三条命令跑一遍能提前定位八成问题# 1. 驱动模块有没有加载 lsmod | grep vmw # 2. 主机共享了哪些目录 vmware-hgfsclient # 3. 有没有现成的挂载点 ls -la /mnt/hgfs第一条命令如果没有任何输出说明 HGFS 模块没加载可以试着手动加载sudo modprobe vmw_vmci sudo modprobe vmhgfs如果模块文件本身不存在那就是 open-vm-tools 没装好回头检查安装过程有没有报错。第二条命令是关键。它能列出你在主机端配置的所有共享名称。如果这里什么都不输出别急着在 Ubuntu 里找原因问题百分之百在主机端要么共享没勾总是启用要么虚拟机没重启过要么当前虚拟机配置根本没保存。第三条命令如果提示目录不存在自己建一个就行挂载点目录必须先存在sudo mkdir -p /mnt/hgfs4. 挂载实操从临时挂载到开机自动生效前面都是准备真正让目录出现内容的动作在这一步。我会按从简到繁的顺序把三种做法都过一遍你可以按需求选。4.1 vmhgfs-fuse 手动挂载与参数逐条拆解先看最直接的临时挂载命令sudo vmhgfs-fuse .host:/ /mnt/hgfs -o subtypevmhgfs-fuse,allow_other这行命令里每个部分都有意义拆开说。.host:/是 HGFS 的虚拟根点号加 host 代表主机侧冒号后面跟共享名。写/表示挂载全部共享写/ws_share表示只挂这一个。-o后面是挂载选项用逗号分隔。subtypevmhgfs-fuse告诉系统这个 FUSE 挂载的具体子类型部分版本的 mount 命令需要它才能正确识别。allow_other是最重要的一个它允许非 root 用户访问挂载点不加这个参数你会发现普通用户进不去目录只有 root 能看。如果你只挂单个共享还想顺便解决权限问题可以写成这样sudo vmhgfs-fuse .host:/ws_share /mnt/hgfs/ws_share \ -o subtypevmhgfs-fuse,allow_other,uid1000,gid1000这里uid和gid是给你的当前用户指定属主。查自己的 ID 很简单id -u # 输出用户 ID通常是 1000 id -g # 输出主组 ID通常也是 1000为什么要显式指定因为 HGFS 驱动默认把文件属主映射成 root普通用户读写会提示权限不足。指定 uid 之后共享目录里的文件在你眼里就归自己所有编辑器保存、脚本创建文件都不会再报错。这是新手最常卡住的点比挂载本身更容易翻车。实操心得先用临时挂载把参数试通确认权限、访问都正常之后再把同样的参数写进开机自启配置。反过来操作的话每次改配置都要重启验证效率极低。4.2 写进 fstab参数、转义与踩坑预警临时挂载重启就没了想开机自动挂载标准做法是写 /etc/fstab。在文件末尾加一行.host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other,defaults,uid1000,gid1000 0 0六个字段分别是设备、挂载点、文件系统类型、挂载选项、dump 备份标志、fsck 检查顺序。后两个对虚拟文件系统没有意义固定写 0 0。这里有几个坑必须提前说。第一改 fstab 之前先备份。如果这行写错了系统可能启动时卡在紧急模式因为 systemd 找不到挂载源就不肯继续。备份命令sudo cp /etc/fstab /etc/fstab.bak第二先测试再重启。写完不要直接重启用这条命令验证配置能否正常应用sudo mount -a没有报错就说明语法和参数都没问题。有报错就去核对路径和选项千万别带着错误配置重启。第三挂载点必须已存在。fstab 不会自动建目录/mnt/hgfs必须提前 mkdir 好否则挂载失败。第四如果共享名带空格fstab 里的空格要转义成\040写成.host:/my\040share。这也是前面建议共享名别用空格的原因。第五如果不希望因为挂载失败导致开机卡住可以加nofail选项.host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other,defaults,uid1000,gid1000,nofail 0 0加了 nofail 之后挂载失败只是少个目录系统照常启动对生产环境和远程维护的机器特别友好。4.3 用 systemd mount unit 替代 fstab 的写法如果你的 Ubuntu 版本较新或者你不喜欢 fstab 那种写错了就开不了机的压迫感可以改用 systemd 挂载单元。它的好处是能精细控制依赖关系比如指定在网络服务就绪后再挂载出错信息也更清楚。创建文件/etc/systemd/system/mnt-hgfs.mount[Unit] DescriptionVMware HGFS shared folders [Mount] What.host:/ Where/mnt/hgfs Typefuse.vmhgfs-fuse Optionsallow_other,defaults,uid1000,gid1000 [Install] WantedBymulti-user.target启用并立即挂载sudo systemctl daemon-reload sudo systemctl enable --now mnt-hgfs.mount这里有个硬性规则单元文件名必须和挂载路径严格对应。路径是/mnt/hgfs单元名就是mnt-hgfs.mount中间的斜杠换成横线开头也不带横线。如果你挂在/mnt/hgfs/ws_share名字就得叫mnt-hgfs-ws_share.mount。名字对不上systemd 会直接报错这个报错信息写得还算清楚看一眼就知道问题在哪。验证挂载结果用这几条systemctl status mnt-hgfs.mount mount | grep hgfs df -h | grep hgfs三条命令分别从服务状态、挂载表、磁盘用量三个角度看确认目录真的挂上了。5. 权限、软链接与中文名共享目录里最容易翻车的三类文件挂载成功只是第一步真正让人抓狂的是后面这些看起来能用但一操作就出错的场景。我把它们单独拎出来讲因为这部分内容你在官方文档里基本看不到。5.1 权限不够的三种典型表现与对应解法表现一目录能进但新建文件提示 Permission denied。这是最典型的属主映射问题。根因是 HGFS 挂载时没指定 uid/gid文件在系统看来属于 root。解法就是在挂载参数里加上uid$(id -u),gid$(id -g)。已经挂载的可以卸载重挂sudo umount /mnt/hgfs sudo vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other,uid1000,gid1000表现二能读能写但脚本执行不了。这是可执行位的问题。HGFS 挂载时可以通过umask控制权限掩码默认值可能会把可执行位抹掉。如果共享目录里放的是 shell 脚本或者二进制文件需要显式指定sudo vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other,uid1000,gid1000,umask022umask022 的含义是从默认权限里去掉组和其他用户的写权限让文件呈现 755 的形态可执行位保留。这个值和系统默认 umask 是反着理解的容易记混我一般直接照抄不改。表现三root 能用普通用户不能用。这就是allow_other没加。FUSE 挂载有个默认安全策略只允许挂载者访问。所以只要不是 root 挂的其他用户全被挡在外面。加上 allow_other 之后如果还不行去检查/etc/fuse.conf里有没有user_allow_other这一行没有的话取消注释。不过用 sudo 挂载时这条限制通常不生效所以加了 allow_other 一般就解决了。我还是建议把这几条权限设置一次性写全省得后面反复调sudo vmhgfs-fuse .host:/ /mnt/hgfs \ -o subtypevmhgfs-fuse,allow_other,uid1000,gid1000,umask0225.2 软链接、Git 仓库、大文件为什么不适合放共享目录软链接是个大坑。HGFS 对符号链接的支持很不完整很多版本里你在主机创建的快捷方式或者 Ubuntu 里ln -s建的链接挂载后会被当成普通文件或者干脆报 Operation not supported。根因是 HGFS 协议本身没有完整实现符号链接的语义驱动只能做降级处理。所以共享目录里尽量别出现软链接Python 虚拟环境、Node.js 的 node_modules 里面全是链接放进去必炸。Git 仓库放共享目录也是自找麻烦。我实测过在共享目录里 clone 一个中等规模仓库git status 要跑十几秒切分支经常提示文件被占用。原因是 Git 需要频繁地创建、重命名、修改权限位而这些操作在 HGFS 上都有额外开销有些权限位还改不了。更好的做法是把仓库放虚拟机本地磁盘用共享目录做代码同步的出口或者干脆用 Git 远程仓库中转。大文件传输速度要有心理预期。我实测过同样一个 1GB 的镜像文件从本机磁盘复制大概十几秒走 HGFS 要一分钟以上。想量化测试可以这么干dd if/dev/zero of/mnt/hgfs/testfile bs1M count500 rm /mnt/hgfs/testfile500MB 顺序写的耗时能给你一个直观感受。如果日常需要搬运大文件走 SSH 通道用 rsync 会快不少因为它有增量算法和压缩选项。中文文件名一般没问题但不是绝对。现代版本的 open-vm-tools 用 UTF-8 传递文件名中文正常显示。但如果主机是 Windows 且文件是用 GBK 编码的老工具创建的可能出现乱码。这种情况没法在挂载层解决只能改名。所以我的建议还是那句共享目录里的文件命名尽量用英文。6. 常见故障速查从空目录到重启失效逐个排下面这张表是我这几年遇到过的所有共享文件夹相关问题的汇总按现象归类对照着查能省很多时间。现象最可能的原因排查动作解决方式/mnt/hgfs 存在但为空未安装 open-vm-tools 或共享未启用跑vmware-hgfsclient看有无输出补装工具包主机端勾选总是启用vmware-hgfsclient无输出主机端共享未保存或虚拟机未重启重新打开虚拟机设置核对保存配置后重启客户机挂载报 unknown filesystem typefuse 依赖缺失apt list --installed | grep fuse安装 fuse3 或 open-vm-tools挂载报 mountpoint is not empty挂载点目录里已有文件ls -la /mnt/hgfs清空目录或换挂载点普通用户无法访问缺少 allow_other 或 uid 参数mount | grep hgfs看选项重新挂载并补全参数能读不能写主机关闭了写入权限检查共享设置里的只读勾选取消只读或改挂载参数重启后挂载消失只做了临时挂载cat /etc/fstab写入 fstab 或 systemd unitfstab 写了但不开机挂载挂载点不存在或语法错误sudo mount -a看报错建目录、修正转义剪贴板复制粘贴失效缺 desktop 包或 Wayland 会话echo $XDG_SESSION_TYPE装 desktop 包切 Xorg 会话拖拽文件失败同上同上改用共享文件夹或 SFTP文件修改不生效主机端缓存未刷新用sync命令强制刷盘客户机里执行sync或重新挂载中文文件名乱码主机文件编码不是 UTF-8在主机端查看文件名编码重命名文件软链接变成普通文件HGFS 不支持链接ls -l看文件类型避免在共享目录使用软链接编译时报 Operation not supported文件锁或权限位不支持查看具体报错文件把编译输出改到本地磁盘排查思路我一般遵循一条原则先分清楚问题在主机侧、驱动侧还是挂载侧。用vmware-hgfsclient判断主机侧用lsmod判断驱动侧用mount和dmesg | tail判断挂载侧。三段式定位比你盲目改参数快得多。dmesg特别有用FUSE 挂载失败的详细原因基本都会打到内核日志里很多人不知道去看。还有个小技巧如果怀疑是缓存问题比如在主机改了文件虚拟机里看到的还是旧内容可以强制卸载重挂sudo umount -l /mnt/hgfs sudo mount -aumount -l是懒卸载即使有进程占用也能先解除挂载关系适合目录被终端或编辑器占着不放的情况。但要注意懒卸载之后目录内容会变成空的假象别误以为文件丢了。7. 什么时候该放弃共享文件夹CIFS 与 SSH 通道的适用边界原生共享文件夹在单机虚拟化场景里足够好用但它有两个绕不过去的局限一是必须以虚拟化平台为依托虚拟机迁到别的宿主机上共享配置就没了二是跨网络场景用不了。这两类需求得换别的方案。7.1 CIFS 挂载重启失效的根治方案主机侧开启 SMB 共享之后Ubuntu 端用 CIFS 挂载是常见做法。临时挂载命令长这样sudo mount -t cifs //192.168.1.20/share /mnt/share \ -o usernameuser,passwordpass,uid1000,gid1000,iocharsetutf8,vers3.0参数含义vers3.0指定 SMB 协议版本新版 Windows 用 3.0 或更高更稳iocharsetutf8解决中文文件名乱码uid/gid还是老问题不指定就归 root。重启后失效是 CIFS 最高频的问题根因有三层。第一层是 fstab 里没写这个最容易解决。写进 fstab 的形态是//192.168.1.20/share /mnt/share cifs credentials/etc/cifs.cred,uid1000,gid1000,iocharsetutf8,vers3.0,nofail,_netdev 0 0第二层是密码明文写在 fstab 里不安全也不方便所以用 credentials 文件sudo tee /etc/cifs.cred /dev/null EOF usernameuser passwordyourpassword EOF sudo chmod 600 /etc/cifs.cred权限必须是 600否则 mount 会拒绝读取这是很多人卡住的地方报错信息里会明确提到permission denied on credentials file但新手往往只看到权限两个字就往目录权限上想。第三层是挂载时机问题。系统启动时可能网络还没就绪CIFS 挂载就失败了。这就是_netdev选项的作用它告诉 systemd 这个挂载需要网络等网络服务起来后再执行。配合nofail即使网络暂时不通也不会卡住启动。这两个选项组合基本能解决九成的 CIFS 开机挂载问题。7.2 SSHFS 与 rsync跨网络、跨平台的通用解法如果虚拟机和主机不在同一台物理设备上或者你需要在多个环境之间同步文件SSH 通道是最通用的方案任何能跑 SSH 的系统之间都适用。方向一主机挂载虚拟机的目录sudo apt install -y sshfs mkdir -p ~/vm_remote sshfs user192.168.1.30:/home/user/project ~/vm_remote \ -o reconnect,ServerAliveInterval15,uid1000,gid1000reconnect让连接断了自动重连ServerAliveInterval定期发心跳包防止空闲断开这两个参数在网络不稳定时特别有用。卸载用fusermount -u ~/vm_remote。方向二把文件从主机推到虚拟机rsync -avz --progress /path/to/source/ user192.168.1.30:/home/user/target/-a是归档模式保留权限和时间戳-v输出详细过程-z传输时压缩。rsync 的最大优势是增量同步第二次传只推变化的部分比整体复制快得多。如果是在 Windows 主机上操作可以用 WinSCP 或者带 SFTP 功能的编辑器图形界面拖拽更省事。还有一条路是用编辑器的远程开发能力直接开虚拟机目录。很多现代 IDE 都支持通过 SSH 连接到远程主机直接编辑远端文件本地不落地任何副本。这种做法在多人协作或者需要严格环境一致性的场景下特别合适避免了两边文件版本不一致的老问题。需要提醒的是网络上关于云主机环境搭建专线接入之类的教程很多但那些场景涉及的配置项和本地虚拟机完全不同不要照着套。虚拟机和物理主机之间的文件互通前面讲的三种方案已经能覆盖绝大多数需求。8. 我的实际使用习惯和几条压箱底建议上面把配置流程和排错方法都过了一遍最后分享几个我自己用了很多年、很少对外讲的习惯。第一共享目录只当传送带不当工作区。我的标准做法是主机上放最新的源码通过共享目录传进虚拟机然后在虚拟机的本地磁盘上建立工作目录用 rsync 或者简单的 cp 同步过去再编译。这样既有共享的便利又避开了 HGFS 的性能和文件锁问题。很多人觉得多一步麻烦但编译一次省下的时间远超过同步的几秒钟。第二永远保留一份能回滚的 fstab 备份。我见过太多人因为一行 fstab 写错机器起不来又不会进救援模式最后只能重装。sudo cp /etc/fstab /etc/fstab.bak这条命令一秒钟能救你一整天。第三把共享相关的命令写成脚本。我习惯在~/bin下放一个mount-share.sh内容就是那行挂载命令平时改了参数直接跑脚本测试不用每次敲长命令。测试通了再固化到 systemd unit 里。脚本和系统配置分离改起来互不影响。第四遇到诡异问题时先怀疑虚拟化平台版本。VMware 不同大版本之间的 HGFS 实现有过几次调整比如旧版默认挂载点、模块名称都有变化。如果你的操作步骤和网上教程完全一致却跑不通很可能不是步骤错了而是版本差异。去虚拟机设置里看一下 Workstation 的版本号再针对性搜索比反复试参数有效得多。第五虚拟机快照是最省事的实验手段。配共享目录、改 fstab、试挂载参数这些操作全都可以在快照之后进行搞砸了直接回滚几十秒的事。我自己在处理不确定的系统级配置时几乎必先打快照。这个习惯让我在折腾各种虚拟化方案时从来没真正弄坏过环境。最后补一个很少被提到但很实用的点如果你需要在同一台主机上的多个虚拟机之间共享文件不要给每台虚拟机都配一遍主机共享目录那样主机上会出现多份副本版本一乱就很难收拾。更合理的做法是选一台虚拟机当文件服务节点开 SSH 或 SMB 服务其他虚拟机通过网络访问它。这样文件只有一份谁改了什么一目了然备份也只需要备份一处。这个思路在没有域控的家庭实验室环境里特别省心我用了两年多再没出现过两边文件不一致的情况。
返回列表