You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Udev钩子自动备份USB内容失效,但脚本单独运行正常求助

UDEV规则触发U盘自动备份失败的排查与解决

问题描述

我在/etc/udev/rules.d中配置了规则,意图实现插入指定厂商的U盘时自动备份内容到指定目录。手动执行脚本一切正常,但U盘插入触发时挂载失败,仅能创建备份目录。相关配置如下:

规则文件80-local.rules

student@student-VirtualBox:/etc/udev/rules.d$ cat 80-local.rules 
SUBSYSTEM=="block", ACTION=="add", ATTRS{idVendor}=="058f", RUN+="/home/student/psop/triggertools/bin/principal.sh" 

脚本principal.sh

#!/bin/bash

log_file="/home/student/psop/logs"

first_script="/home/student/psop/triggertools/bin/trigger.sh"

echo Starting scrip ... > "$log_file"

bash "$first_script"

脚本trigger.sh

#!/bin/bash

log_file="/home/student/psop/logs"
backup_dir="/home/student/psop/backupdir"
mount_dir="/home/student/psop/mountdir"
usb_device="/dev/sdb1"


if [ ! -d "$backup_dir" ]
then
    mkdir -p "$backup_dir"
fi

sudo systemd-mount --no-block --automount=no --collect "$usb_device" "$mount_dir" >> "$log_file" 2>&1
sleep 5

echo "Continut folder de montare: " >> "$log_file"
ls "$mount_dir" >> "$log_file"

if [ $? -eq 0 ]
then
    sudo /usr/local/bin/backup "$mount_dir" "$backup_dir" >> "$log_file" 2>&1
    sleep 5
    sudo umount "$usb_device" >> "$log_file"
else
    echo "Eroare la montarea dispozitivului!" >> "$log_file" 2>&1
fi

核心问题点

  1. UDEV运行环境受限:UDEV触发的脚本在无完整用户环境的后台进程中运行,sudo无法获取用户权限上下文,导致挂载命令执行失败。
  2. 硬编码设备路径:固定写死/dev/sdb1,但U盘设备路径可能随系统存储设备状态变化,导致脚本找不到正确设备。
  3. 设备初始化时机:UDEV触发add动作时,设备可能尚未完全初始化完成,此时执行挂载会失败,手动执行时设备已就绪所以正常。

修复步骤

1. 修改UDEV规则,传递设备信息并调度到用户会话

更新80-local.rules,用systemd-run将脚本放到用户会话环境中运行,同时传递设备路径:

SUBSYSTEM=="block", ACTION=="add", ATTRS{idVendor}=="058f", ENV{DEVNAME}=="?*", RUN+="/usr/bin/systemd-run --user --scope /home/student/psop/triggertools/bin/principal.sh $env{DEVNAME}"
  • --user:让脚本在当前用户的会话环境中运行,获取完整权限和环境变量
  • $env{DEVNAME}:将UDEV识别到的实际设备路径传递给脚本

2. 修改脚本接收动态设备路径

更新principal.sh,把设备路径参数传递给trigger.sh:

#!/bin/bash

log_file="/home/student/psop/logs"
first_script="/home/student/psop/triggertools/bin/trigger.sh"

echo Starting script ... > "$log_file"

bash "$first_script" "$1"  # 传递UDEV传来的设备路径

更新trigger.sh,替换硬编码的设备路径为传入参数:

#!/bin/bash

log_file="/home/student/psop/logs"
backup_dir="/home/student/psop/backupdir"
mount_dir="/home/student/psop/mountdir"
usb_device="$1"  # 接收设备路径参数

# 检查是否获取到设备路径
if [ -z "$usb_device" ]; then
    echo "未获取到有效设备路径" >> "$log_file"
    exit 1
fi

if [ ! -d "$backup_dir" ]
then
    mkdir -p "$backup_dir"
fi

# 移除sudo,利用systemd-run的用户权限上下文执行挂载
systemd-mount --no-block --automount=no --collect "$usb_device" "$mount_dir" >> "$log_file" 2>&1
sleep 8  # 延长等待时间,确保设备完全初始化

echo "Continut folder de montare: " >> "$log_file"
ls "$mount_dir" >> "$log_file"

if [ $? -eq 0 ]
then
    /usr/local/bin/backup "$mount_dir" "$backup_dir" >> "$log_file" 2>&1
    sleep 5
    umount "$usb_device" >> "$log_file"
else
    echo "Eroare la montarea dispozitivului!" >> "$log_file" 2>&1
fi

3. 配置用户免权限挂载(可选)

如果用户执行systemd-mount仍有权限问题,创建sudoers规则文件:

sudo nano /etc/sudoers.d/student-mount

添加内容:

student ALL=(ALL) NOPASSWD: /usr/bin/systemd-mount, /usr/bin/umount

设置文件权限:

sudo chmod 0440 /etc/sudoers.d/student-mount

4. 重新加载UDEV规则

使修改后的规则生效:

sudo udevadm control --reload-rules
sudo udevadm trigger

内容的提问来源于stack exchange,提问作者Samuel Edi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 12:37:55