Linux下Udev触发USB自动备份脚本失效及动态挂载问题
问题解决思路与步骤
一、修复Udev触发时backup程序不执行的问题
手动执行正常但Udev触发失败,核心原因是Udev执行环境与终端环境存在差异,按以下步骤排查修复:
- 使用绝对路径调用backup程序:Udev的PATH环境变量范围极窄,脚本中不能用
./backup这类相对路径,必须写入完整路径,比如/home/samuel/usb-project/backup。 - 添加延迟确保设备就绪:USB插入后需要短暂时间完成初始化挂载,在Udev规则中加入sleep延迟。示例规则:
ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", RUN+="/bin/sh -c 'sleep 3; /path/to/your/script.sh'" - 添加日志定位问题:在脚本关键步骤写入日志文件,方便排查执行断点:
echo "[$(date)] 脚本启动执行" >> /var/log/usb-backup.log /home/samuel/usb-project/backup >> /var/log/usb-backup.log 2>&1 echo "[$(date)] 脚本执行结束" >> /var/log/usb-backup.log - 移除backup的交互依赖:如果backup程序需要终端输入或交互操作,必须修改为非交互模式——Udev运行环境没有终端,无法处理交互逻辑。
二、动态获取USB设备路径(替代硬编码)
利用Udev自身的环境变量直接传递设备路径,无需固定写死/dev/sdb1:
方法1:Udev规则传递设备路径给脚本
修改Udev规则,将设备路径作为参数传入脚本:
ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", RUN+="/path/to/your/script.sh $env{DEVNAME}"
在脚本中通过位置参数接收:
USB_DEV=$1 # 后续用$USB_DEV替代硬编码路径 mount $USB_DEV /mnt/usb-temp
方法2:脚本直接读取Udev环境变量
Udev会将自身的环境变量传递给执行的脚本,直接在脚本中调用$DEVNAME即可获取当前触发的设备路径:
USB_DEV=$DEVNAME mount $USB_DEV /mnt/usb-temp
额外验证:确保设备为有效文件系统
可在脚本中添加判断,过滤非文件系统设备:
if blkid $USB_DEV | grep -q "TYPE=\"vfat\"\|TYPE=\"ext4\""; then mount $USB_DEV /mnt/usb-temp # 执行backup备份操作 else echo "[$(date)] 不支持的文件系统类型" >> /var/log/usb-backup.log fi
配套注意事项
- 提前创建挂载目录:
sudo mkdir -p /mnt/usb-temp,并确保脚本拥有挂载权限(可通过sudo执行脚本,或在Udev规则中指定运行用户)。 - 修改Udev规则后需重载生效:
sudo udevadm control --reload-rules && sudo udevadm trigger
内容的提问来源于stack exchange,提问作者Samuel Edi
相关产品推荐
相关产品推荐

