UDEV触发BASH脚本无法挂载设备的问题求助
按UUID自动挂载设备的UDEV问题排查与解决
问题详情
尝试通过UDEV规则实现设备按UUID自动挂载,相关配置及故障如下:
UDEV规则
文件路径:/etc/udev/rules.d/99-local.rules
ACTION=="add", ENV{ID_FS_UUID}=="12CB-F616", SYMLINK+="masterkey", RUN+="/usr/bin/mountkey.sh"
挂载脚本
文件路径:/usr/bin/mountkey.sh
LOG_FILE="/tmp/key-mount.log" sudo mount /dev/masterkey /mnt/masterkey > /tmp/key-mount.log MOUNT_POINT="$(findmnt -n -o TARGET --source '/dev/masterkey')" echo "$MOUNT_POINT" >> "$LOG_FILE" if [ -n $MOUNT_POINT ]; then echo "Device with UUID: $UUID mounted at $MOUNT_POINT" >> "$LOG_FILE" else echo "Error: Device with UUID: $UUID not mounted" >> "$LOG_FILE" fi
Sudo配置
通过visudo编辑/etc/sudoers添加免密权限:
root ALL=(ALL:ALL) ALL root ALL=NOPASSWD:/usr/bin/mount vagrant ALL= NOPASSWD: /usr/bin/mount
故障现象
UDEV触发脚本后挂载失败,日志/tmp/key-mount.log无mount执行痕迹,仅输出:
Device with UUID: mounted at
移除脚本中的sudo、更换为sh脚本均无效,但手动执行sudo mount /dev/sdnX /mnt/masterkey可正常挂载。
系统环境:Vagrant运行archlinux/archlinux镜像,内核版本6.10.10-arch1-1
解决步骤
1. 修复脚本变量与权限问题
- UDEV的
RUN指令默认以root身份执行,脚本中无需sudo,直接调用mount即可 - 脚本中
$UUID未定义,需引用UDEV传递的ID_FS_UUID环境变量 - 重定向输出时包含错误信息(
2>&1),方便排查问题 - 提前检查并创建挂载点,避免因目录缺失导致挂载失败
修改后的脚本:
LOG_FILE="/tmp/key-mount.log" MOUNT_DIR="/mnt/masterkey" UUID="$ID_FS_UUID" # 创建挂载点(如果不存在) if [ ! -d "$MOUNT_DIR" ]; then mkdir -p "$MOUNT_DIR" echo "Created mount directory: $MOUNT_DIR" >> "$LOG_FILE" fi # 执行挂载并记录所有输出 mount /dev/masterkey "$MOUNT_DIR" >> "$LOG_FILE" 2>&1 MOUNT_POINT="$(findmnt -n -o TARGET --source '/dev/masterkey')" echo "Detected mount point: $MOUNT_POINT" >> "$LOG_FILE" if [ -n "$MOUNT_POINT" ]; then echo "Success: Device with UUID $UUID mounted at $MOUNT_POINT" >> "$LOG_FILE" else echo "Failed: Device with UUID $UUID could not be mounted" >> "$LOG_FILE" fi
2. 优化UDEV规则
UDEV触发add动作时设备可能未完全就绪,添加SUBSYSTEM=="block"限定块设备,同时用WAIT_FOR="dev"确保设备节点创建完成:
ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_UUID}=="12CB-F616", SYMLINK+="masterkey", RUN+="/usr/bin/mountkey.sh", WAIT_FOR="dev"
3. 清理冗余sudo配置
由于UDEV以root身份执行脚本,无需为root配置mount免密权限,可将/etc/sudoers中相关行删除,仅保留vagrant的配置(如果需要):
root ALL=(ALL:ALL) ALL vagrant ALL= NOPASSWD: /usr/bin/mount
4. 调试验证
- 重新加载UDEV规则:
udevadm control --reload-rules - 触发UDEV规则(替换为你的设备路径):
udevadm trigger /sys/block/sdnX - 查看UDEV日志排查问题:
journalctl -u systemd-udevd.service -f
内容的提问来源于stack exchange,提问作者rustymanito
相关产品推荐
相关产品推荐

