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
英文地址,請注明出處:http://en.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 )”的功能,所有這些功能均由 …