1. 背景
在 Ubuntu 系统中,USB 硬盘、移动硬盘盒插拔后,Linux 可能重新分配设备名称:
例如第一次:
/dev/sdb1
重新插拔后:
/dev/sdc1
如果使用固定设备路径:
/dev/sdb1
会导致挂载失败。
Linux 中推荐使用:
UUID
作为磁盘唯一标识。
本文实现:
USB硬盘插入
|
|
udev监听
|
|
systemd触发服务
|
|
根据UUID识别
|
|
自动挂载
|
|
/data/usb/<UUID>
适用版本:
- Ubuntu 20.04
- Ubuntu 22.04
- Ubuntu 24.04
- Ubuntu 26.04
支持文件系统:
- NTFS
- ext4
- XFS
- exFAT
2. 方案特点
优点
- 不依赖
/dev/sdX - 支持 USB 设备编号变化
- 自动识别硬盘
- 支持拔插
- 支持 Docker 数据目录
- 支持服务器和桌面环境
不推荐方式
不要使用:
/dev/sda1
/dev/sdb1
原因:
USB设备顺序不固定。
3. 安装依赖
安装 NTFS 支持
Ubuntu:
bash
apt update
apt install -y ntfs-3g
检查:
bash
mount.ntfs-3g --version
4. 创建挂载目录
统一规划:
bash
mkdir -p /data/usb
最终效果:
/data/usb
├── UUID1
├── UUID2
└── UUID3
5. 创建自动挂载脚本
创建文件:
bash
vim /usr/local/bin/usb-auto-mount.sh
内容:
bash
#!/bin/bash
MOUNT_ROOT="/data/usb"
mkdir -p "$MOUNT_ROOT"
for dev in $(lsblk -lnpo NAME,TYPE | awk '$2=="part"{print $1}')
do
# 已经挂载跳过
if mount | grep -q "^$dev "
then
continue
fi
fstype=$(blkid -s TYPE -o value "$dev" 2>/dev/null)
case "$fstype" in
ntfs|ext4|xfs|exfat)
;;
*)
continue
;;
esac
uuid=$(blkid -s UUID -o value "$dev")
[ -z "$uuid" ] && continue
mount_point="${MOUNT_ROOT}/${uuid}"
mkdir -p "$mount_point"
if ! mountpoint -q "$mount_point"
then
case "$fstype" in
ntfs)
mount -t ntfs-3g "$dev" "$mount_point"
;;
*)
mount "$dev" "$mount_point"
;;
esac
if [ $? -eq 0 ]
then
logger -t usb-auto-mount \
"mount $dev UUID=$uuid -> $mount_point"
else
logger -t usb-auto-mount \
"mount failed $dev"
fi
fi
done
exit 0
增加执行权限:
bash
chmod +x /usr/local/bin/usb-auto-mount.sh
6. 创建 systemd 服务
创建:
bash
vim /etc/systemd/system/usb-auto-mount.service
内容:
ini
[Unit]
Description=USB UUID Auto Mount Service
After=local-fs.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/usb-auto-mount.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
重新加载:
bash
systemctl daemon-reload
测试启动:
bash
systemctl start usb-auto-mount
查看状态:
bash
systemctl status usb-auto-mount
设置开机启动:
bash
systemctl enable usb-auto-mount
7. 配置 udev 监听
udev 负责监听硬盘插拔事件。
创建规则:
bash
vim /etc/udev/rules.d/99-usb-auto-mount.rules
添加:
bash
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd*", RUN+="/bin/systemctl restart usb-auto-mount.service"
ACTION=="remove", SUBSYSTEM=="block", KERNEL=="sd*", RUN+="/bin/systemctl restart usb-auto-mount.service"
重新加载:
bash
udevadm control --reload-rules
触发:
bash
udevadm trigger
8. 测试
插入移动硬盘。
查看日志:
bash
journalctl -t usb-auto-mount -f
示例:
mount /dev/sdb1 UUID=ABCD-1234 -> /data/usb/ABCD-1234
查看挂载:
bash
df -h
结果:
/dev/sdb1
Mounted on:
/data/usb/ABCD-1234
9. Ubuntu Desktop 注意事项
Ubuntu Desktop 默认使用:
udisks2
负责:
- 文件管理器自动挂载
- 桌面显示移动设备
- 普通用户挂载
如果机器作为 NAS 或服务器使用,可以关闭:
bash
systemctl disable --now udisks2
查看:
bash
systemctl status udisks2
恢复:
bash
systemctl enable --now udisks2
10. 防止误挂系统盘
建议增加过滤。
查看系统根分区:
bash
findmnt /
获取:
UUID=xxxx
脚本中排除:
bash
if [ "$uuid" = "$ROOT_UUID" ]
then
continue
fi
避免扫描:
- /
- /boot
- 系统 LVM
11. Docker 使用
例如:
硬盘:
/data/usb/ABCD-1234
Docker:
yaml
services:
backup:
volumes:
- /data/usb/ABCD-1234:/backup
设备重新插入:
/dev/sdb1
变成:
/dev/sdc1
Docker路径不受影响。
12. 推荐目录规划
生产环境:
/data
├── docker
│
├── mysql
│
├── redis
│
├── backup
│
└── usb
|
├── UUID1
|
└── UUID2
13. 与其他方案比较
| 方案 | 稳定性 | 推荐 |
|---|---|---|
| /dev/sdX挂载 | 低 | ❌ |
| while循环扫描 | 中 | ⭐⭐⭐ |
| fstab UUID | 高 | ⭐⭐⭐⭐ |
| udev + systemd + UUID | 最高 | ⭐⭐⭐⭐⭐ |
14. 最终推荐架构
对于 Ubuntu Desktop + ToDesk + Docker + 移动硬盘盒:
推荐:
固定数据盘
|
+-- fstab UUID
移动硬盘
|
+-- udev
|
+-- systemd
|
+-- UUID挂载
Docker
|
+-- 使用固定/data路径
该方案可以长期稳定运行,避免 USB 硬盘重新识别导致路径变化问题。