很多用 Ubuntu 的朋友都会遇到同一个场景:手头一台 Windows 机器上存了一堆资料,想在 Ubuntu 里直接读写这些文件,而不是每次都用 U 盘拷贝来拷贝去。双系统用户尤其痛苦,我当年就是 Ubuntu 和 Windows 来回切换,传个文件还得靠网盘中转,后来学会挂载共享文件夹之后,整个人都舒服了。
这篇内容我打算把 Ubuntu 挂载 Windows 共享文件夹这件事从头到尾捋一遍,从 Windows 端怎么设置共享、Ubuntu 端怎么装组件、怎么写挂载命令,到最关键的“开机自动挂载”和“权限问题排查”,全给你讲透。内容适合刚接触 Linux 的新手,也适合已经挂载成功但想搞懂原理、想解决各种报错的老手。
先说结论:Ubuntu 访问 Windows 共享文件夹,核心就是走 SMB/CIFS 协议,通过 mount -t cifs 把 Windows 的共享目录挂载成 Ubuntu 本地的一个目录。实际操作中你会碰到协议版本不对、用户映射失败、权限没给够、开机挂载失败等一系列问题,我会把我踩过的坑和排查思路都写出来。
1. 动手前的准备:Windows 端要做好的三件事
很多人一上来就在 Ubuntu 里敲 mount 命令,结果报各种错,最后发现是 Windows 那边根本就没配置好。别嫌这一步啰嗦,Windows 端的准备直接决定了后面挂载顺不顺利。
1.1 确认共享目录与访问协议
Windows 的共享功能依赖 SMB 协议,这是微软家的网络文件共享协议,Linux 内核里对应的实现叫 CIFS。Windows 从 10 和 Server 2016 之后默认启用的是 SMB 3.0 及更高版本,SMB 1.0 协议因为安全漏洞太多,默认是关闭的。
在 Windows 上创建共享目录很简单:
- 右键你想共享的文件夹(比如 D:\Share),选择“属性 -> 共享 -> 高级共享”。
- 勾选“共享此文件夹”,设置共享名称(Share Name),建议用纯英文,避免后续挂载时出现字符集问题。
- 点击“权限”,添加 Everyone 或者指定用户,并赋予“读取”或“读取/写入”权限。
这里有一个很多新手不知道的坑:Windows 的共享权限有两层,一层是“共享权限”,另一层是 NTFS 文件系统权限。最终用户能拿到什么权限,取的是两层权限的“交集”,也就是说最严格的哪个生效。比如共享权限给了 Everyone 完全控制,但 NTFS 权限里只有读取,那最终就是只读。我建议共享权限直接给 Everyone 完全控制,具体的读写控制交给 NTFS 权限来管,这样逻辑清晰,排查问题的时候也好办。
另外一个重点:查看 Windows 机器的局域网 IP。Win+R 输入 cmd,然后敲 ipconfig,找到“IPv4 地址”那一行,记下来,后面挂载会用到。建议你在 Windows 上设置静态 IP,或者至少在路由器里绑定 DHCP,不然 Windows 的 IP 变了,Ubuntu 端的挂载配置就全废了。这个坑我踩过,Windows 自动获取 IP 重启后变了,Ubuntu 这边 fstab 里写的旧 IP,直接导致开机挂载失败。
1.2 Windows 端的防火墙和访问账户准备
Windows 防火墙默认会放行文件和打印机共享相关的规则,也就是 445 端口(SMB 协议默认端口)。但如果你的 Windows 装过第三方安全软件,或者手动修改过防火墙规则,很可能会拦掉 SMB 流量。
建议在挂载前先在 Windows 上确认防火墙状态:控制面板 -> Windows Defender 防火墙 -> 允许应用或功能通过防火墙,找到“文件和打印机共享”,确保专用网络里勾选了允许。如果你不确定配置是否正确,直接在 Ubuntu 端用 nc 命令测一下端口通不通:
bash复制nc -zv 192.168.1.100 445
如果显示 Connection succeeded,说明端口通;如果 timeout,大概率就是防火墙问题,先去 Windows 防火墙看看规则。
再有一个容易忽略的点:Windows 访问共享时的账户凭证。Windows 家庭版默认管理员账户需要设置密码才能通过网络共享访问。你用微软账户登录的话,共享访问用的凭证就是你的微软账户邮箱和密码(PIN 不行);用本地账户的话,就是本地用户名加登录密码。如果没有密码是不能通过网络共享访问的,这个要先在 Windows 上有心理准备。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Ubuntu 端的核心操作:从安装组件到手动挂载
Windows 那边准备好了,接下来轮到 Ubuntu 发力。这一部分我会把命令一步一步拆开讲,每个参数为什么这么写都说明白,目的不是为了让你机械复制,而是让你遇到问题时知道怎么调整。
2.1 安装 cifs-utils 并确认内核支持
Ubuntu 默认没有安装 CIFS 挂载工具,第一步先装:
bash复制sudo apt update
sudo apt install cifs-utils -y
cifs-utils 这个包提供了 mount.cifs 工具,是挂载 SMB/CIFS 共享的关键。装完可以确认一下版本:
bash复制mount.cifs -V
内核方面的支持不用太担心,主流 Linux 发行版的 kernel 都编译了 CIFS 模块。但如果你想用 SMB3.0 以上的协议,建议内核版本在 4.2 以上。Ubuntu 20.04 及以上的默认内核都没问题。确认内核是否支持 CIFS:
bash复制grep CIFS /boot/config-$(uname -r)
看到 =m 或 =y 就说明内核支持。
还有一点,强烈建议先用 ping 测一下 Ubuntu 到 Windows 的网络连通性:
bash复制ping -c 4 192.168.1.100
网络不通的情况我见过不少,很多人以为挂载命令写错了,结果排查半天发现是两台机器不在同一个网段,或者 Windows 开了网络隔离。先确保基础网络没问题再往下走。
2.2 手动挂载命令详解与参数选择
挂载目录先建好,然后执行 mount 命令:
bash复制sudo mkdir -p /mnt/winshare
sudo mount -t cifs //192.168.1.100/Share /mnt/winshare -o username=yourname,password=yourpass,uid=1000,gid=1000,iocharset=utf8,vers=3.0
这一串命令看起来简单,但里面的参数值得逐个说清楚:
-t cifs:指定文件系统类型为 cifs,这是 Linux 访问 Windows 共享的标准做法。//192.168.1.100/Share:Windows 的 IP 加共享名。注意这里用的是斜杠而不是 Windows 里的反斜杠,新手经常搞错。/mnt/winshare:本地挂载点,需要有写权限或者用 sudo 创建。username/password:Windows 的访问凭证。uid/gid:指定挂载后目录归属的本地用户和用户组 ID。不设置的话,挂载目录默认归 root,普通用户只能看不能写。查看当前用户的 uid 和 gid 用id命令。iocharset=utf8:字符集设为 UTF-8,解决中文文件名乱码问题。如果你的文件名是 GBK 编码的老文件,可以考虑iocharset=gb2312,但一般 utf8 就够了。vers=3.0:指定 SMB 协议版本。这是最容易踩坑的参数,Windows 10 之后的系统默认 SMB 3.0 以上,但老版本 Windows 或者 NAS 设备可能只支持 SMB 1.0/2.0。如果你用的是老款 Windows 7 或者某些嵌入式 NAS,可能需要vers=2.0甚至vers=1.0。不过从安全角度考虑,不建议在生产环境使用 vers=1.0。
挂载成功后,进入目录试试读写:
bash复制cd /mnt/winshare
ls
touch test.txt
echo "hello" > test.txt
能正常创建文件就说明读写权限没问题。
2.3 为什么要用 credentials 文件而不是明文密码
上面命令行直接写 password 的方式虽然简单,但有一个严重问题:密码会留在 shell 历史里。用 history 命令一翻就露馅了。而且以后配置开机自动挂载,fstab 文件里写明文密码也容易暴露。
推荐的做法是创建独立的凭证文件:
bash复制sudo nano /etc/samba/credentials
文件内容格式如下:
code复制username=yourname
password=yourpass
domain=WORKGROUP
然后把这个文件的权限改成只有 root 可读写:
bash复制sudo chmod 600 /etc/samba/credentials
挂载命令改成:
bash复制sudo mount -t cifs //192.168.1.100/Share /mnt/winshare -o credentials=/etc/samba/credentials,uid=1000,gid=1000,iocharset=utf8,vers=3.0
这样命令简洁了不少,密码也不会暴露在进程列表中。domain=WORKGROUP 这一行,如果你 Windows 用的默认工作组就可以填 WORKGROUP,如果用域环境就填对应的域名,不填一般也不会报错。
3. 开机自动挂载的配置与避坑
手动挂载成功后,很多人会想每次开机自动挂载,省得敲命令。这个需求很合理,但 fstab 配置了不能正常开机的问题也很常见。我见过太多人因为 fstab 写错,Ubuntu 直接卡在启动页面进不了系统。这一节我会把安全配置 fstab 的姿势讲清楚。
3.1 写入 fstab 的正确姿势
fstab 是 Linux 里管理文件系统挂载的核心配置文件,开机时 systemd 会读取这个文件并挂载所有条目。在 /etc/fstab 末尾追加一行:
code复制//192.168.1.100/Share /mnt/winshare cifs credentials=/etc/samba/credentials,uid=1000,gid=1000,iocharset=utf8,vers=3.0,nofail,_netdev,x-systemd.automount 0 0
这个配置比手动挂载多了几个关键参数:
nofail:如果挂载失败,不阻止系统继续启动。没有这个参数,Windows 没开机或者 IP 变了,Ubuntu 就会卡死或进入紧急模式。_netdev:告诉系统这是一个网络设备挂载,在 network 服务就绪后再挂载。不加这个参数,系统可能在网络还没初始化的时候就尝试挂载,导致失败。x-systemd.automount:使用 systemd 的自动挂载特性,延迟到真正访问该目录时才触发挂载。这个参数能显著减少开机等待时间,特别是 Windows 不在线的时候。
修改完 fstab 后,强烈建议先验证配置是否正确,再重启:
bash复制sudo mount -a
这个命令会重新挂载 fstab 里的所有条目。没有报错就说明配置没问题。然后用 df -h | grep winshare 确认挂载成功。
3.2 fstab 写错导致开不了机的抢救方案
万一你踩坑了,fstab 写错导致开机进入紧急模式(emergency mode),不要慌。系统会提示输入 root 密码或 Ctrl+D 跳过,这时候执行:
bash复制mount -o remount,rw /
然后编辑 fstab:
bash复制nano /etc/fstab
删掉写错的那一行或者把 nofail 加上,保存后重启。我建议你每次改完 fstab 都先执行 sudo mount -a 验证一遍,不要直接重启。另外,配置自动挂载时最好让 Windows 和 Ubuntu 都是固定 IP,Windows 用静态 IP 或 DHCP 保留绑定,Ubuntu 也用同样的方式,这样 IP 不会随便变。
关于 systemd 自动挂载还有一个细节:x-systemd.automount 会让 df -h 在访问目录之前不显示挂载信息,这是正常现象,因为你一访问目录它就会触发挂载。有的朋友以为挂载失败了,实际上只是 auto mount 的特性。
4. 常见问题排查实录
挂载 Windows 共享文件夹,报错千奇百怪,但绝大多数都能归到几个典型类别里。我把这几年折腾过的报错信息整理成一张速查表,再逐个展开讲处理思路。
| 报错信息 | 可能原因 | 解决方案 |
|---|---|---|
| mount error(2): No such file or directory | 共享名/路径写错 | 检查 //IP/ShareName 是否正确 |
| mount error(13): Permission denied | 凭证错误或权限不足 | 检查用户名密码、共享权限和 NTFS 权限 |
| mount error(112): Host is down | SMB 协议版本不匹配 | 尝试 vers=2.0 或 vers=1.0 |
| mount error(115): Connection timed out | 防火墙拦截或网络不通 | 检查防火墙、ping、nc 测试 445 端口 |
| mount error(95): Operation not supported | 内核或工具不支持某特性 | 升级内核或 cifs-utils,去掉多余挂载参数 |
| wrong fs type, bad option, bad superblock | 没装 cifs-utils | apt install cifs-utils |
| Only root can mount | 权限不够 | 使用 sudo 挂载 |
| Permission denied 写文件失败 | uid/gid 配置不对 | 指定 uid/gid 为当前用户 |
4.1 挂载报错“wrong fs type”怎么办
这个报错本质上就是系统不知道 cifs 类型怎么处理,纯cifs-utils 没装。确认命令:
bash复制sudo apt install cifs-utils
which mount.cifs
如果装了还报错,可能是 mount 程序不认识这个文件系统类型,检查一下 /sbin/mount.cifs 是否存在。正常安装后 mount.cifs 会在 /sbin 目录下,如果不在,可能是安装不完整,重装一遍。
4.2 用户名或密码正确却提示 Permission denied
这个情况最让人抓狂,明明 Windows 上能正常访问共享,Ubuntu 挂载就是报 mount error(13): Permission denied。
首先要确认 Windows 账户密码没有变化,其次检查是不是微软账户登录。如果你是微软账户登录的系统,共享访问凭证不是你电脑的 PIN 码,而是完整的微软账户邮箱和密码。你可以尝试在 Windows 里新建一个专门用于共享的本地账户,赋予访问该共享目录的权限,然后用这个专用账户来挂载。这个方法还有一个好处:即使用户密码过期也不会影响日常登录状态。
另一个原因是 Windows 的“安全设置”里启用了“计算机账户”限制。如果 Windows 是专业版以上,组策略里可能设置了“拒绝从网络访问此计算机”等策略。Win+R 输入 gpedit.msc -> 计算机配置 -> Windows 设置 -> 安全设置 -> 本地策略 -> 用户权限分配,找到“从网络访问此计算机”和“拒绝从网络访问此计算机”,确保当前访问用户不在被拒绝的列表里。家庭版没有组策略,但一般不会有这个限制。
4.3 挂载后目录归属 root,普通用户无法读写
把挂载参数里的 uid 和 gid 改成当前用户 id 即可:
bash复制sudo id
假设输出是 uid=1000(username) gid=1000(username),那你挂载时加 uid=1000,gid=1000 就行。如果设置了 uid/gid 还是不行,检查 umask 参数,默认 cifs 挂载的目录权限是 0755,文件是 0644,如果你需要在共享目录里保存可执行文件,可以用 file_mode=0777,dir_mode=0777 来调整。不过要谨慎,给太高权限在共享目录里乱传文件容易出问题。
4.4 访问共享目录里的符号链接报错
Windows 共享目录里的符号链接,在 Linux 端默认是没办法直接访问的。CIFS 协议对符号链接的处理跟本地文件系统不一样,需要在挂载参数里加 mfsymlinks 才能识别 Windows 侧的符号链接。如果你在共享目录里创建了大量符号链接,并且需要在 Ubuntu 端访问,记得加上这个参数:
bash复制sudo mount -t cifs //192.168.1.100/Share /mnt/winshare -o credentials=/etc/samba/credentials,uid=1000,gid=1000,mfsymlinks,vers=3.0
如果不需要访问符号链接,不建议加这个参数,因为会带来一些安全上的考量。
4.5 访问大目录卡顿、复制速度慢
如果你跨平台复制大文件,CIFS 协议本身性能相比 NFS 或者局域网的 iSCSI 是有差距的,但可以通过挂载参数优化:
rsize=65536和wsize=65536:加大读写缓冲区。这两个参数定义了 CIFS 读写的最大块大小,默认值可能偏小,手动提高到 64KB 能明显改善大文件传输性能。cache=loose:允许更激进的文件缓存策略。适合单机访问且不担心文件被其他客户端并发修改的情况。如果有多台机器同时访问同一个共享目录,还是用默认缓存策略更安全。noatime:不更新访问时间戳,减少不必要的网络 IO。
综合起来:
bash复制sudo mount -t cifs //192.168.1.100/Share /mnt/winshare -o credentials=/etc/samba/credentials,uid=1000,gid=1000,noatime,rsize=65536,wsize=65536,cache=loose,vers=3.0
实际测试下来,大文件传输速度能提升 20% 到 40%,但也要看你的网络环境。千兆网环境下,这个优化效果比较明显;百兆网络的话,瓶颈在物理网速,再怎么优化也就那么回事。
5. 扩展经验:从挂载到真正的跨平台协作
挂载只是第一步,挂载成功之后还有一堆实际问题要处理。权限映射、文件编码、多用户访问,这些弄不明白,共享目录用起来还是会磕磕绊绊。
5.1 理解 Linux 与 Windows 权限模型的差异
Windows 共享目录的权限模型基于 ACL(访问控制列表),每个人的权限独立配置;Linux 传统权限基于 owner/group/other 三段式,两者差异很大。CIFS 协议挂载时,Linux 端看到的文件权限是 Windows 端根据挂载参数“模拟”出来的。
挂载参数里的 uid/gid 决定了 Linux 端哪个用户拥有共享目录里的所有文件。这跟 Windows 端某个文件是张三创建的 L 的 ACL 权限不是一回事——你挂载之后所有文件都归你指定的 uid/gid,你设成 1000,那就全是 ubuntu 用户的。这种映射机制决定了多用户场景下,你不能指望在 Linux 端用 chmod/chown 去改变共享目录里文件的属主和权限,因为那只是操作 CIFS 层的虚拟权限,Windows 端真正生效的还是 NTFS ACL。
如果你需要精细化的权限控制,核心做法是在 Windows 侧配置好 NTFS ACL,在 Ubuntu 侧限定 uid/gid 挂载参数。Linux 端不管配多少用户,最终网络层访问 Windows 的只有挂载时的那个 Windows 账户,所以 Windows 的 ACL 是按这个账户来判定权限的,明白这个逻辑才能把权限配清楚。
5.2 多用户共用同一挂载点的场景
如果一台 Ubuntu 服务器有多个用户都需要访问同一个 Windows 共享,最省事的方案是直接用 root 挂载,再通过设置 uid/gid 让用户访问。但每个用户的权限都一样,隔离性比较差。
想要每人一个凭证、权限互不干扰,可以用 multiuser 挂载参数加上 cifscreds 工具。这个方案稍微复杂,我先简单提一下,有需要的朋友可以深入研究:
bash复制sudo mount -t cifs //192.168.1.100/Share /mnt/winshare -o credentials=/etc/samba/credentials,multiuser,sec=ntlmssp
然后每个普通用户登录后执行:
bash复制cifscreds add 192.168.1.100
系统会提示输入 Windows 用户名和密码,验证通过后该用户访问挂载点时,使用自己的 Windows 凭证而不是默认凭证。这个方案适合需要在共享目录中区分用户权限的场景。注意,cifscreds 需要 cifs-utils 4.7 以上版本。
5.3 反向场景:Windows 访问 Ubuntu 目录怎么配
挂载需求解决了从 Ubuntu 访问 Windows,反过来如果你想在 Windows 上访问 Ubuntu 的目录,最常用的方案是在 Ubuntu 上装 samba 服务。这个方向也值得一提,因为很多朋友搭好共享之后,发现文件从 Ubuntu 复制到 Windows 共享目录倒是挺方便,但反过来又从 Windows 复制不回去,于是干脆双向共享。
Ubuntu 装 samba:
bash复制sudo apt install samba -y
然后编辑 /etc/samba/smb.conf,在文件末尾添加自己的共享配置:
ini复制[myshare]
path = /home/yourname/share
available = yes
valid users = yourname
read only = no
browsable = yes
public = yes
writable = yes
设置 samba 用户密码:
bash复制sudo smbpasswd -a yourname
重启 samba:
bash复制sudo systemctl restart smbd
Windows 端用 \\ubuntu-ip\myshare 访问。这个配套方案能让你在两台系统间双向传文件,基本可以摆脱 U 盘了。
5.4 关于 SMB 协议版本选择的最终建议
Windows 版本和 SMB 协议版本的对应用表整理如下,方便你对照选择:
| Windows 版本 | 默认支持的 SMB 协议 | 建议 vers 参数 |
|---|---|---|
| Windows 7 / Server 2008 R2 | SMB 2.1 | vers=2.1 |
| Windows 8 / Server 2012 | SMB 3.0 | vers=3.0 |
| Windows 10 / Server 2016+ | SMB 3.1.1 | vers=3.0 或 3.1.1 |
| 老款 NAS(群晖旧系统等) | SMB 1.0/2.0 | 根据设备参数调整 |
在新时代的安全标准下,SMB 1.0 强烈不建议使用,它带来过严重的勒索软件传播事件。如果你的 Windows 机器还开着 SMB 1.0,建议在 Windows 功能里把它关掉,然后用 vers=2.0 或 3.0 挂载。Linux 的 CIFS 内核模块默认允许的协议版本一般较高,如果你不指定 vers 参数,它会自动协商一个最好的协议版本。但自动协商并不总可靠,老设备偶尔会失败,所以我还是建议手动指定,稳定又心里有底。
6. 开机自动挂载后依然失败的特殊处理
前面讲了 fstab 里加 nofail 和 x-systemd.automount 能避免开机卡死,但有些场景下,即使这些参数都加了,自动挂载还是会出幺蛾子。比如 Windows 在 Ubuntu 启动之后才开机,或者网络服务初始化比较慢,systemd 可能提前执行了挂载动作,结果失败了。
这种“启动时 Windows 还没就绪”的场景,解决方案是用 systemd 的 mount 单元来替代 fstab 条目,并设置等待时间。但这种方式配置起来不如 fstab 直观。另一种做法是写一个 NetworkManager 的 dispatcher 脚本,在网络完全就绪之后再执行 mount。简单粗暴的做法是把挂载命令写进 /etc/rc.local,但在现代 systemd 系统里 rc.local 默认不执行,需要先创建 systemd 服务单元。
思路大概这样:写一个脚本 /usr/local/bin/mount-winshare.sh:
bash复制#!/bin/bash
# 等待 Windows 主机就绪后挂载共享目录
for i in $(seq 1 30); do
if ping -c 1 -W 1 192.168.1.100 > /dev/null 2>&1; then
# 尝试挂载,失败就等 5 秒重试
while ! mountpoint -q /mnt/winshare; do
mount -t cifs //192.168.1.100/Share /mnt/winshare -o credentials=/etc/samba/credentials,uid=1000,gid=1000,iocharset=utf8,vers=3.0,nofail
sleep 5
done
exit 0
fi
sleep 10
done
exit 1
赋予执行权限:
bash复制sudo chmod +x /usr/local/bin/mount-winshare.sh
创建 systemd 服务 /etc/systemd/system/mount-winshare.service:
ini复制[Unit]
Description=Mount Windows share
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mount-winshare.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
启用服务:
bash复制sudo systemctl enable mount-winshare.service
这个方案的好处是即使 Windows 没有开机,服务也会在后台等待,不会阻塞系统启动。如果你经常遇到 Windows 和 Ubuntu 不同步开机的情况,用方案比单纯依赖 fstab 的 nofail 更顺手。
7. 折腾分享文件夹一年半载后的体会
我这几年在不同场景下反复用过 Ubuntu 挂载 Windows 共享,有笔记本双系统的临时传文件,有家里 NAS 共享目录的固定挂载,也有服务器上跨平台归档的自动化任务。每一次折腾完,我觉得最值钱的经验反而很简单:与其跟一串复杂参数死磕,不如先把网络通不通、用户名对不对、协议版本匹配不匹配这三件事查清楚。百分之八十的问题都出在这三个地方。
挂载参数里最核心的就四个:credentials 凭证文件、uid/gid 用户映射、vers 协议版本、nofail 和 _netdev 这两个开机参数。把这几个吃透了,基本就能应对所有常规需求。至于那些高级玩法,比如 multiuser 多用户、cache 缓存策略,等你基础挂载用顺了再研究也不迟,别一开始就整的花里胡哨,出了问题反而难排查。
从实际使用的角度看,CIFS 挂载虽然在传输效率上比本地文件系统低一些,但胜在兼容性和易用性,跨平台场景下目前还是最省心的方案。等到你用顺手了,还能进一步把它和自动化任务结合起来,比如定时备份、日志收集、文件同步这些工作,都能直接跑在挂载目录上,相当于给跨平台协作打了地基。
