Linux
树莓派3B 采用Samba + Cockpit搭建NAS
Linux 修改开机启动 boot splash logos
Linux 下将 .po 文件编译成 .mo 文件
Python 使用 gettext 模块实现国际化
XFCE 桌面优化配置
香橙派3B 使用 WiringOP 读取 MPU6050
香橙派4 LTS 安装 WiringPi
Linux 图形界面切换到 FB 界面
校表仪 tg-timer 算法笔记
Linux 安装 EtherCat Igh
EetherCat Igh 常用指令
树莓派镜像 DIY 制作
树莓派5B 安装64位实时系统 preempt RT 补丁
linux 的 lightdm 桌面管理器下隐藏光标(鼠标)
Linux 上使用 MPD (Music Player Daemon)
Linux 自动化交互式命令行工具 —— expect
Linux GTK 界面开发
Debian系统中修改主机名
使用Python + GTK3.0 开发嵌入式GUI
Raspberry Pi 5修改系统内存分页大小解决安装esp-matter 出现的<jemalloc>: Unsupported systeom page size 错误
树莓派 linux 安装和使用clash 做VPN
树莓派自动挂载硬盘
非控制台或ssh登录用户尝试启动Xorg图形服务器
XFCE4 电源管理器配置管理
Linux PulseAudio 声卡配置和检测
IBUS修改输入法和设置切换快捷键
在 Moode Audio 中实现开机自动启动 `startx`
crontab 任务
树莓派外设耗电检测
linux 终端自动登录
linux创建新用户
linux service通过xinit启动GTK应用程序
Linux 非桌面的图形环境安装和配置
香橙派3b板载音频输出没有声音调试
使用 udev 规则修改权限实现屏幕亮度调节
Linux udev 介绍
鲁班猫4 ubuntu22.04 屏幕背光 udev 自动配置化
ubuntu22.04 动态壁纸配置
使用 udisksctl 的可靠 USB 自动挂载方案(基于 systemd-run)
通过udev规则U盘自动挂载
OpenWRT 磊科N60pro路由器刷机
本文档使用 MrDoc 发布
-
+
首页
通过udev规则U盘自动挂载
``` # 安装必要的文件系统支持 sudo apt update sudo apt install -y exfat-fuse exfat-utils ntfs-3g sudo apt install -y udisks2 ``` ## 1. `udev`规则文件`/etc/udev/rules.d/99-automount_usb.rules` `biqu@BTT-CB1:~$ cat /etc/udev/rules.d/99-automount_usb.rules` ``` # 所有品牌U盘通用规则(添加事件) ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z][0-9]*", ENV{ID_BUS}=="usb", RUN+="/usr/local/bin/smart_usb_mount.sh" # 所有品牌U盘通用规则(移除事件) ACTION=="remove", SUBSYSTEM=="block", KERNEL=="sd[a-z][0-9]*", ENV{ID_BUS}=="usb", RUN+="/usr/local/bin/smart_usb_mount.sh" ``` ``` # 添加环境变量传递和权限提升 ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z][0-9]*", ENV{ID_BUS}=="usb", \ RUN+="/bin/bash -c 'DEVNAME=%k ACTION=%s /usr/local/bin/smart_usb_mount.sh'" ACTION=="remove", SUBSYSTEM=="block", KERNEL=="sd[a-z][0-9]*", ENV{ID_BUS}=="usb", \ RUN+="/bin/bash -c 'DEVNAME=%k ACTION=%s /usr/local/bin/smart_usb_mount.sh'" ``` ## U盘自动挂载程序 ```bash biqu@BTT-CB1:~$ cat /usr/local/bin/smart_usb_mount.sh #!/bin/bash # /usr/local/bin/smart_usb_mount.sh # 设置参数(根据实际情况修改) USER="biqu" # 替换为你的用户名 TARGET_DIR="/home/$USER/printer_data/gcodes" STATE_FILE="/tmp/usb_mount_state" LOG_FILE="/tmp/usb_mount.log" # 确保日志文件可写 touch "$LOG_FILE" chmod a+w "$LOG_FILE" # 日志功能 log() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" } log "设备事件触发: 动作=$ACTION, 设备=$DEVNAME" # 获取设备的基础名称(如sdb1) get_dev_basename() { [ -n "$DEVNAME" ] && basename "$DEVNAME" } # 清除旧的挂载状态 cleanup_mount() { if [ -f "$STATE_FILE" ]; then local mounted_dev mounted_dev=$(head -n1 "$STATE_FILE" | awk '{print $1}') mount_point=$(head -n1 "$STATE_FILE" | awk '{print $2}') log "清理旧挂载: 设备=$mounted_dev, 挂载点=$mount_point" # 卸载绑定挂载 if grep -qs "$TARGET_DIR" /proc/mounts; then umount -l "$TARGET_DIR" >> "$LOG_FILE" 2>&1 && log "已卸载绑定挂载" fi # 卸载原始挂载 if [ -n "$mount_point" ] && grep -qs "$mount_point" /proc/mounts; then umount -l "$mount_point" >> "$LOG_FILE" 2>&1 && log "已卸载原始挂载" # 移除空挂载点 if [ -d "$mount_point" ]; then rmdir "$mount_point" >> "$LOG_FILE" 2>&1 && log "已移除挂载点目录" fi fi # 删除状态文件 rm -f "$STATE_FILE" fi } # 处理设备添加 handle_add() { current_dev=$(get_dev_basename) log "检测到新设备: $current_dev" # 确保设备存在 if [ ! -b "/dev/$current_dev" ]; then log "错误:设备 /dev/$current_dev 不存在!" return 1 fi # 创建目标目录 mkdir -p "$TARGET_DIR" chown "$USER:$USER" "$TARGET_DIR" # 清理旧的挂载 cleanup_mount # 创建临时挂载点 MOUNT_POINT=$(mktemp -d /media/usb-XXXXXX) chown "$USER:$USER" "$MOUNT_POINT" # 挂载设备(支持常见文件系统) log "挂载设备 /dev/$current_dev 到 $MOUNT_POINT" mount -t auto -o nosuid,nodev,uid=$USER,gid=$USER "/dev/$current_dev" "$MOUNT_POINT" >> "$LOG_FILE" 2>&1 if [ $? -ne 0 ]; then log "挂载失败!尝试其他文件系统支持..." # 尝试常见文件系统 for fs_type in vfat ntfs exfat ext4 ext3 ext2; do mount -t $fs_type -o nosuid,nodev,uid=$USER,gid=$USER "/dev/$current_dev" "$MOUNT_POINT" >> "$LOG_FILE" 2>&1 if [ $? -eq 0 ]; then log "成功挂载为 $fs_type 文件系统" break fi done # 检查是否成功 grep -qs "$MOUNT_POINT" /proc/mounts if [ $? -ne 0 ]; then log "所有挂载尝试均失败!" rmdir "$MOUNT_POINT" return 1 fi fi # 绑定到目标目录 log "绑定挂载 $MOUNT_POINT 到 $TARGET_DIR" mount --bind "$MOUNT_POINT" "$TARGET_DIR" >> "$LOG_FILE" 2>&1 chown -R "$USER:$USER" "$TARGET_DIR" # 保存状态 echo "$current_dev $MOUNT_POINT" > "$STATE_FILE" log "挂载成功!设备内容可在 $TARGET_DIR 访问" } # 处理设备移除 handle_remove() { current_dev=$(get_dev_basename) log "设备移除: $current_dev" # 检查移除设备是否是当前挂载的设备 if [ -f "$STATE_FILE" ]; then mounted_dev=$(head -n1 "$STATE_FILE" | awk '{print $1}') if [ "$mounted_dev" = "$current_dev" ]; then log "正在卸载当前使用的设备: $current_dev" cleanup_mount else log "移除的设备 $current_dev 不是当前挂载的设备 (挂载的是 $mounted_dev)" fi else log "无活动挂载状态" fi } # 主执行逻辑 case "$ACTION" in add) handle_add ;; remove) handle_remove ;; *) log "未知动作: $ACTION" ;; esac ``` ```bash # 设置权限 sudo chmod +x /usr/local/bin/smart_usb_mount.sh sudo chown biqu:biqu /usr/local/bin/smart_usb_mount.sh # 重载 udev 规则 sudo udevadm control --reload-rules sudo udevadm trigger 或 sudo udevadm control --reload sudo systemctl restart systemd-udevd # 测试脚本 # 模拟 U 盘插入 sudo ACTION=add DEVNAME=/dev/sda1 /usr/local/bin/smart_usb_mount.sh sudo ACTION=remove DEVNAME=/dev/sda1 /usr/local/bin/smart_usb_mount.sh # 检查挂载结果 ls -la ~/printer_data/gcodes # 查看详细日志 cat /tmp/usb_mount.log ``` ## 3. 查看日志 ```bash tail -f /tmp/usb_mount.log ``` ``` # 查看U盘信息 biqu@BTT-CB1:~$ sudo blkid /dev/sda1 /dev/sda1: LABEL="SYSTEM-BOOT" UUID="4422-E958" BLOCK_SIZE="512" TYPE="exfat" PARTUUID="d7068db8-01" ```
qingkai
2025年11月13日 11:15
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码