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

相关推荐
布鲁飞丝2 小时前
彩笔运维勇闯机器学习--cpu与qps的线性关系
运维·人工智能·机器学习
kaoa0003 小时前
Linux入门攻坚——84、网络虚拟化技术-1
linux·运维·服务器
RisunJan3 小时前
Linux命令-shutdown(安全关闭或重启系统)
linux·服务器·安全
2601_965798474 小时前
MTDb Movie & TV Database Script Setup, Caching, and SEO Guide
linux·服务器·数据库·php
我头发多我先学4 小时前
linux系统编程:初识进程
linux·运维·服务器
Freak嵌入式4 小时前
版本混乱 / 依赖缺失?uPyPi:MicroPython 版 PyPI,彻底解决库管理混乱
linux·服务器·数据库·单片机·嵌入式硬件·性能优化·依赖倒置原则
云飞云共享云桌面4 小时前
SolidWorks—天津智能装备工厂1台高配主机共享给10个研发用
运维·服务器·自动化·汽车·制造
苍狗T4 小时前
LVS相关知识总结
linux·运维·服务器·lvs
lightqjx5 小时前
【Linux系统】基础 IO
linux·c语言·重定向·缓冲区·文件io·文件的系统调用