Bash脚本实现:按命名规则挂载首个匹配分区并忽略后续同SAN项
解决方案:按SAN匹配磁盘分区并挂载(避免重复)
问题分析
你遇到的核心问题包括:
- 重复挂载同SAN的分区导致覆盖
- 脚本执行时设备未就绪引发"特殊设备不存在"错误
- 变量解析/传递异常
以下是仅用Linux核心工具实现的解决方案,满足遍历匹配、仅挂载首个同SAN实例、登录前执行的要求。
实现脚本
创建/usr/local/bin/mount_san_volumes.sh脚本,赋予执行权限:
#!/bin/bash # 确保udev设备就绪,解决"无法打开块设备"问题 udevadm settle # 收集需要匹配的目标值(/usr/local/etc/ini/system/下的目录名) TARGETS=() for dir in /usr/local/etc/ini/system/*/; do TARGETS+=("$(basename "$dir")") done # 跟踪已处理的SAN,避免重复挂载 declare -A PROCESSED_SANS # 遍历所有带PARTLABEL的磁盘分区 lsblk -no PARTLABEL,NAME | while read -r partlabel devname; do # 跳过无PARTLABEL的设备 [[ -z "$partlabel" ]] && continue # 分割PARTLABEL字段:ORG-DOMAIN-SAN-SITE-DEVICE-VOLUME IFS='-' read -r org domain san site device volume <<< "$partlabel" [[ -z "$san" ]] && continue # 检查当前SAN是否已处理,跳过已处理项 [[ -n "${PROCESSED_SANS[$san]}" ]] && continue # 检查当前partlabel是否包含任一目标值 match_found=0 for target in "${TARGETS[@]}"; do if [[ "$partlabel" == *"$target"* ]]; then match_found=1 break fi done [[ $match_found -eq 0 ]] && continue # 定义挂载点 mount_point="/path/to/${target}_${san}" # 创建挂载点(如果不存在) mkdir -p "$mount_point" # 检查挂载点是否已挂载,未挂载则执行挂载 if ! mountpoint -q "$mount_point"; then # 使用PARTLABEL挂载,比/dev路径更可靠 mount "PARTLABEL=$partlabel" "$mount_point" # 标记当前SAN为已处理 PROCESSED_SANS[$san]=1 fi done
关键细节说明
设备就绪处理:
加入udevadm settle确保系统完成设备枚举,解决脚本执行过早导致的"无法打开块设备"错误,这是手动挂载可行但脚本失败的常见原因。避免重复挂载:
用关联数组PROCESSED_SANS跟踪已处理的SAN标识,一旦处理过同SAN的首个匹配项,后续同SAN设备直接跳过。可靠挂载方式:
使用PARTLABEL=$partlabel作为挂载源,而非/dev/$devname,避免设备名(如sdb1、sdc1)随重启变化导致的挂载失败。变量解析处理:
所有变量引用均用双引号包裹,避免空格或特殊字符导致的解析异常;通过basename正确提取目录名,避免路径干扰。
登录前执行配置
方法1:使用rc.local(适用于支持sysvinit兼容的系统)
- 在
/etc/rc.local的exit 0前添加:/usr/local/bin/mount_san_volumes.sh - 赋予rc.local执行权限:
chmod +x /etc/rc.local
方法2:使用systemd服务(适用于systemd系统)
- 创建
/etc/systemd/system/mount-san-volumes.service:[Unit] Description=Mount SAN volumes on boot After=udev.target local-fs.target [Service] Type=oneshot ExecStart=/usr/local/bin/mount_san_volumes.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target - 启用并启动服务:
systemctl daemon-reload systemctl enable --now mount-san-volumes.service
内容的提问来源于stack exchange,提问作者Techsplorer
相关产品推荐
相关产品推荐

