Ubuntu 使用 udev + systemd + UUID 实现 USB 硬盘自动挂载

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 硬盘重新识别导致路径变化问题。

相关推荐
暴力求解15 小时前
Linux网络---传输层协议TCP(二)
linux·服务器·开发语言·网络·tcp/ip
JoyCong199816 小时前
ToDesk个人版、专业版、游戏版、设计版、性能版、团队版权益介绍
大数据·运维·游戏·远程工作·远程操作
ltl16 小时前
序列化格式深度对比:Protobuf、FlatBuffers、Cap’n Proto
linux
lengjingzju16 小时前
编译与调试完全指南—第17章 总结
linux
ltl16 小时前
容器网络性能真相:veth vs macvlan vs eBPF 数据面
linux
Elastic 中国社区官方博客17 小时前
ES95:面向 Elasticsearch 时间序列指标的自适应压缩
大数据·运维·elasticsearch·搜索引擎·架构·全文检索
mqiqe18 小时前
AgentScope Java 2.0 Agent 状态存储(AgentStateStore)深度解析:构建可恢复、可扩展的智能体运行时
java·运维·网络
mennekes18 小时前
数据中心安全配电设备如何选择?
运维·人工智能·科技·安全·制造
CSDN1211018 小时前
麒麟 V10 安装 Node-RED、IEC 104 协议插件及界面汉化
linux·编辑器·vim
开始学AI19 小时前
Codex2API Docker 使用宿主机代理:OAuth Token 兑换 403 问题排查与解决方案
运维·docker·容器