OpenEuler操作系统中检测插入的USB设备并自动挂载

OpenEuler操作系统中检测插入的USB设备并自动挂载

项目需求:工控机上openeuler操作系统是无界面版本的,在工控机上连接了激光雷达,当激光雷达采集完数据,我们要将采集数据导入u盘,故需要在工控机上插入u盘,操作系统自动检测并挂载u盘,进而导出数据到u盘

整体原理:
U盘插拔 -> 触发udev规则 -> 开启systemd服务 -> 调用实际挂载/卸除脚本

1.硬件连接与内核识别

当 U 盘插入工控机的 USB 接口时,内核会自动识别该 USB 设备,为其分配块设备节点(如/dev/sda,其中sda1为第一个分区,即/dev/sda1)。内核会记录设备的基本信息(如文件系统类型ext4、UUID 等,可通过blkid命令查看)。

2.udev 监测设备事件并触发规则

内核识别设备后,udev(设备管理守护进程) 会监测到 “设备添加” 事件(ACTION==“add”),并匹配你配置的/etc/udev/rules.d/99-usb-mount.rules规则:
规则中SUBSYSTEM=="block"指定只处理块设备(U 盘属于块设备),KERNEL=="sd[a-z][0-9]"匹配 U 盘分区(如sda1、sdb2等)。
当事件匹配时,udev 会通过TAG+="systemd"和ENV{SYSTEMD_WANTS}="usb-mount@%k.service"通知 systemd,触发名为usb-mount@%k.service的服务(%k会替换为实际设备名,如sda1)。

创建udev 规则
自动挂载udev规则

sudo vi /etc/udev/rules.d/99-usb-mount.rules

写入以下内容

ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z][0-9]", TAG+="systemd", ENV{SYSTEMD_WANTS}="usb-mount@%k.service"
ACTION=="remove", SUBSYSTEM=="block", KERNEL=="sd[a-z][0-9]", RUN+="/bin/logger 'udev remove event: device=%k, env=$env{}'", TAG+="systemd", ENV{SYSTEMD_WANTS}="usb-umount@%k.service"

自动卸除udev规则

sudo vi /etc/udev/rules.d/99-usb-umount.rules

写入以下内容

ACTION=="remove", SUBSYSTEM=="block", KERNEL=="sd[a-z][0-9]", ENV{SYSTEMD_WANTS}="usb-umount@%k.service", RUN+="/usr/bin/logger udev remove event triggered for %k"

UDEV 规则的作用
udev 是 Linux 系统的设备管理框架,负责监测硬件设备的 “添加 / 移除” 事件,并根据规则执行预设操作。你配置的规则核心作用如下:
(1)事件匹配
ACTION==“add”:只响应 “设备添加” 事件(即 U 盘插入时触发)。
SUBSYSTEM==“block”:限定只处理块设备(U 盘、硬盘等存储设备,排除鼠标、键盘等 USB 设备)。
KERNEL==“sd[a-z][0-9]”:精确匹配 U 盘分区(如sda1、sdb3,sd是 SCSI 磁盘的前缀,[a-z]是设备序号,[0-9]是分区号)。

(2)触发后续操作
TAG+=“systemd”:给事件添加systemd标签,让 systemd 接管事件处理(替代传统的RUN+直接执行命令,更可靠)。
ENV{SYSTEMD_WANTS}=“usb-mount@%k.service”:指定触发的 systemd 服务,%k是动态变量,自动替换为设备名(如sda1),即实际启动usb-mount@sda1.service。

(3)移除事件处理
ACTION==“remove”:响应 U 盘移除事件,通过RUN+="/bin/logger …"记录日志,并触发卸载服务usb-umount@%k.service,避免数据丢失。

3.systemd 服务执行挂载脚本

systemd 接收到 udev 的触发信号后,启动usb-mount@sda1.service(以sda1为例),执行服务中定义的挂载逻辑:
服务通过ExecStart=/root/workspace/auto_mount_usb.sh %I调用挂载脚本(%I传入设备名,如sda1)。

脚本需完成实际挂载操作:检查挂载点(如/mnt/usb)是否存在,执行文件系统检查(如e2fsck),最终通过mount命令将/dev/sda1挂载到/mnt/usb。

挂载成功 / 失败的日志会写入/var/log/usb_mount.log,便于排查问题(如你之前遇到的mount failed可在此日志中查看细节)。

创建systemd 服务

自动挂载usb的systemd服务

vi /etc/systemd/system/usb-mount@.service

写入以下内容

[Unit]
Description=Mount USB device to /mnt/usb
DefaultDependencies=no
After=local-fs.target[Service]
Type=oneshot
ExecStart=/root/workspace/auto_mount_usb.sh %I
TimeoutSec=30
StandardOutput=append:/var/log/usb_mount.log
StandardError=append:/var/log/usb_mount.log[Install]
WantedBy=sysinit.target

自动取消挂载usb的systemd服务

vi /etc/systemd/system/usb-umount@.service

写入以下内容

[Unit]
Description=Unmount USB device from /mnt/usb
DefaultDependencies=no[Service]
Type=oneshot
ExecStart=/root/workspace/auto_unmount_usb.sh %I
TimeoutSec=30
StandardOutput=append:/var/log/usb_mount.log
StandardError=append:/var/log/usb_mount.log[Install]
WantedBy=sysinit.target

实际挂载脚本

vi auto_mount_usb.sh

写入以下内容

echo "Processing device node: $usb_dev"if [[ ! -b "$usb_dev" ]]; thenecho "Device node $usb_dev does not exist or is not a block device"exit 1
fimount_dir="/mnt/usb"sudo rm -rf "$mount_dir"/* 2>/dev/null
sudo mkdir -p "$mount_dir" || {echo "Failed to create mount directory: $mount_dir"exit 1
}udevadm settletimeout=20
while ! blkid "$usb_dev" >/dev/null 2>&1 && [[ $timeout -gt 0 ]]; doecho "Waiting for blkid to detect filesystem on $usb_dev... ($timeout s left)"sleep 1((timeout--))
doneif ! blkid "$usb_dev" >/dev/null 2>&1; thenecho "Device $usb_dev has no recognized filesystem"exit 1
fifs_type=$(blkid -o value -s TYPE "$usb_dev")
echo "Detected filesystem type: $fs_type"if mount | grep -q "^$usb_dev"; thenecho "Device $usb_dev is already mounted"mount | grep "^$usb_dev"exit 0
fiif [[ "$fs_type" == ext* ]]; thenecho "Running e2fsck for $usb_dev"e2fsck -fp "$usb_dev" || echo "e2fsck returned non-zero, continuing"
fiuid=$(id -u)
gid=$(id -g)case "$fs_type" inext*)mount_options="defaults";;ntfs)mount_options="defaults,uid=$uid,gid=$gid,iocharset=utf8,utf8";;exfat)mount_options="defaults,uid=$uid,gid=$gid,iocharset=utf8,fmask=0022,dmask=0022";;vfat)mount_options="defaults,uid=$uid,gid=$gid,iocharset=utf8,fmask=0022,dmask=0022";;*)mount_options="defaults,uid=$uid,gid=$gid,iocharset=utf8";;
esacecho "Mounting $usb_dev at $mount_dir with options: $mount_options"
if mount -t "$fs_type" -o "$mount_options" "$usb_dev" "$mount_dir"; thenecho "Mounted $usb_dev at $mount_dir"df -hT "$mount_dir" | awk 'NR==1; NR>1{print}'echo "To unmount: umount \"$mount_dir\""
elseecho "Mount failed for $usb_dev"sudo rm -rf "$mount_dir"/* 2>/dev/nullexit 1
fiecho "==========================="

实际取消挂载脚本

vi auto_unmount_usb.sh
#!/usr/bin/env bash# USB auto-unmount script for fixed mount point
# Version: 1.1
# Date: 2025-06-09export PATH=/usr/sbin:/usr/bin:/sbin:/binLOGFILE="/var/log/usb_mount.log"
exec >> "$LOGFILE" 2>&1echo "==========================="
echo "[$(date '+%Y-%m-%d %H:%M:%S')] USB auto-unmount triggered"usb_dev="$1"
if [[ -z "$usb_dev" ]]; thenecho "No device node provided to script"exit 1
fimount_dir="/mnt/usb"echo "Processing device node: $usb_dev"if mountpoint -q "$mount_dir"; thenecho "Mount point $mount_dir is mounted, attempting to unmount"cd /if umount "$mount_dir"; thenecho "Unmounted successfully"elseecho "Normal umount failed, trying lazy unmount"if umount -l "$mount_dir"; thenecho "Lazy unmount succeeded"elseecho "Lazy unmount failed"exit 1fifi
elseecho "Mount point $mount_dir not mounted or does not exist"
fiif [ -d "$mount_dir" ]; thenecho "Cleaning up mount directory: $mount_dir"rm -rf "${mount_dir:?}/"* 2>/dev/null || trueecho "Mount directory cleaned"
elseecho "Mount directory $mount_dir does not exist"
fiecho "==========================="

systemd 服务(usb-mount@.service)的作用
systemd 是 Linux 的系统和服务管理器,负责管理进程生命周期。你配置的usb-mount@.service是一个 “模板服务”(通过@支持动态参数),核心作用如下:
(1)定义服务依赖与时机
After=local-fs.target:确保服务在本地文件系统初始化完成后启动,避免挂载点(如/mnt/usb)未就绪的问题。
DefaultDependencies=no:禁用默认依赖,避免服务被不必要的系统事件阻塞。
(2)执行挂载逻辑
Type=oneshot:服务为 “一次性任务”(挂载是瞬时操作,完成后自动退出)。
ExecStart=/root/workspace/auto_mount_usb.sh %I:调用挂载脚本,%I传入设备名(如sda1),脚本需实现具体的挂载逻辑(检查、挂载、日志等)。
(3)日志管理
StandardOutput=append:/var/log/usb_mount.log和StandardError=append:/var/log/usb_mount.log:将挂载过程的输出和错误日志写入指定文件,便于调试(如之前的mount failed可在此日志中查看具体原因)。
(4)模板化设计
服务名中的@允许传入动态参数(如usb-mount@sda1.service、usb-mount@sdb2.service),无需为每个 U 盘分区单独创建服务,简化配置。

4.加载配置

sudo udevadm control --reload-rules
sudo systemctl daemon-reload

查看日志

cat /var/log/usb_mount.log

5.测试

未插入U盘


插入u盘

再次拔出u盘,似乎自动卸除还有点问题,但不影响项目功能,留个bug [狗头],先不改了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88711.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Spring 中上下文传递的那些事儿》Part 11:上下文传递最佳实践总结与架构演进方向

📝 Part 11:上下文传递最佳实践总结与架构演进方向 经过前面几篇文章的深入探讨,我们已经系统性地学习了 Spring 应用中上下文传递的各种技术原理、常见问题以及解决方案。从 Web 请求上下文到异步任务、从多租户隔离到日志脱敏,…

使用云虚拟机搭建hadoop集群环境

使用云虚拟机搭建hadoop集群环境 安装jdk17 配置docker网络 docker network create --subnet172.18.0.0/16 hadoop 172.18.0.0:这是子网的网络地址,也就是这个网络的起始地址。/16:这是子网掩码(Network Mask)&#x…

【机器学习】吴恩达机器学习课程代码作业-Python版本

吴恩达老师的机器学习课程作业是MATLAB版本(Octave)的,现在有点过时了,我参考了几位大牛的代码,将作业改成了Python3.6版本,并做了中文注释,推荐使用Jupyter notebook。Python作业使用了原版数据…

2025年人工智能、虚拟现实与交互设计国际学术会议

重要信息 官网:www.aivrid.com 时间:2025年10月17-19日 地点:中国-东莞 部分介绍 征稿主题 包括但不限于: 生物特征 模式识别 机器视觉 专家系统 深度学习 智能搜索 自动编程 智能控制 智能机器…

SHA-256算法流程分析与详解——Github工程结合示例和动画演示

近日笔者在学习区块链的相关知识,接触到SHA-256算法,这里做一个知识梳理和总结。 强烈推荐大家自行去学习下面链接github上的工程,作者的动画演示和解释做的非常出色,逻辑非常清晰,B站搬运的对应的油管的讲解视频也放…

CSPNet: A New Backbone that can Enhance Learning Capability of CNN (CSP模块)

3. Method 方法 3.1 Cross Stage Partial Network 跨阶段局部网络 3.1.1 Cross Stage Partial Network 跨阶段局部网络 3.1.1.1 ResNet 和 DenseNet 的优缺点主流的卷积神经网络(CNN)架构,如ResNet [8]、ResNeXt [37]、DenseNet [11]&#x…

前端学习4:小白入门注册表单的制作(包括详细思考CSS、JS实现过程)

这篇我们来做一个简单表单,即常见的注册页面吧~学习完这篇我们将学习到Input、label、CSS伪类、CSS入门、更多的JS操作等。。一、首先明确需求:直接模仿常见的注册页面,包括:用户名、Email、性别(单选按钮男/女&#x…

强化学习 (RL) 新突破:超越游戏,走向复杂现实决策

强化学习 (RL) 新突破:超越游戏,走向复杂现实决策 强化学习(Reinforcement Learning, RL)作为人工智能的核心范式之一,历经数十年的发展,正迎来一场深刻的范式转移。曾以战胜人类顶尖选手的Alph…

2025年6-7月AI领域关键进展:从药物研发到全球监管--AI深度融入产业与社会

2025年6月至7月,人工智能领域继续以惊人速度发展,在技术突破、行业应用、政策法规、企业战略及学术研究等方面取得了一系列重要里程碑。以下为关键动态:一、技术突破: AI向生命科学和认知科学纵深挺进DeepMind启动AI设计药物人体试…

【TOOL】ubuntu升级cmake版本

文章目录一、下载cmake脚本二、安装一、下载cmake脚本 在编译新工程时遇到cmake版本过低的情况,到 cmake官网 下载指定cmake安装脚本: 若需下载指定版本,见上图右上角蓝框。 二、安装 # 赋予可执行权限 sudo chmod x cmake-3.31.8-linux-x8…

GMSK调制解调系统的matlab性能仿真,对比维特比解调,1bit差分解调,2bit差分解调

目录 1.前言 2.算法运行效果图预览 3.算法运行软件版本 4.部分核心程序 5.算法仿真参数 6.算法理论概述 7.参考文献 8.算法完整程序工程 1.前言 GMSK(Gaussian Minimum Shift Keying,高斯最小频移键控)是一种连续相位调制技术,基于MSK调制改进而…

SQL138 连续两次作答试卷的最大时间窗

SQL138 连续两次作答试卷的最大时间窗 问题分析 找出2021年至少有两天作答的用户计算每个用户连续两次作答的最大时间窗基于历史数据预测在这个时间窗内平均会做多少套试卷 版本1 with-- 功能​:筛选2021年至少有两天作答的用户及其作答记录-- 子查询找出2021年…

TensorFlow2 study notes[2]

文章目录tf.autodiff.ForwardAccumulatorreferencestf.autodiff.ForwardAccumulator the function can be used to achieve the Computation of Jacobian-vector products with forward-mode autodiff. primals is variables need to watch.tangents is direction vector. …

稳定币将成为新时代的重要金融工具

在数字经济加速渗透的今天,加密货币作为一种新型价值载体,正深刻改变着全球金融的运作逻辑。其中,稳定币与非稳定币构成了加密货币生态的两大支柱,二者在设计逻辑、应用场景和市场表现上呈现出显著差异。 稳定币锚定法定货币 稳定币是一类以法定货币、大宗商品或其他资产…

Constants

本节是《Solidity by Example》的中文翻译与深入讲解,专为零基础或刚接触区块链开发的小白朋友打造。我们将通过“示例 解说 提示”的方式,带你逐步理解每一段 Solidity 代码的实际用途与背后的逻辑。 Solidity 是以太坊等智能合约平台使用的主要编程语…

五镜头倾斜摄影相机的技术优势与应用原理

倾斜摄影技术作为三维实景建模的核心手段,其硬件设计直接影响数据采集效率与模型质量。在众多镜头配置方案中,五镜头结构(下视前、后、左、右四个倾斜视角)已成为行业主流选择。这一设计并非偶然,而是基于严苛的技术需…

ThinkSound V2版 - 一键给无声视频配音,为AI视频生成匹配音效 支持50系显卡 一键整合包下载

ThinkSound 是阿里通义实验室开源的首个音频生成模型,它能够让AI像专业“音效师”一样,根据视频内容生成高度逼真、与视觉内容完美契合的音频。 ThinkSound 可直接应用于影视后期制作,为AI生成的视频自动匹配精准的环境噪音与爆炸声效&#x…

如何从0开始构建自己的第一个AI应用?(Prompt工程、Agent自定义、Tuning)

一、前言 从0开始基于自定义Agent构建AI应用,涉及从创建智能Agent到使用、测试及优化提示词等一系列步骤。前置:什么是LLM、Prompt、Mcp和Agent? 二、步骤一:规划和设计AI应用 在创建AI应用之前,你需要明确应用的目标…

Java ThreadLocal详解:从原理到实践

Java ThreadLocal详解:从原理到实践(图解极简示例) 一、什么是ThreadLocal?——线程的"专属储物柜" ThreadLocal 是 Java 提供的线程本地存储机制,通俗来说,它能为每个线程创建一个独立的变量副本…

如何在 Visual Studio Code 中使用 Cursor AI

在当今快节奏的开发环境中,像 Cursor AI 这样的 AI 工具正在彻底改变开发人员编写和管理代码的方式。Cursor AI 通过提供智能代码建议、自然语言编辑和多文件项目更新功能,增强了“ Visual Studio Code (VS Code )”的功能,所有这些功能均由 …