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

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

关键细节说明

  1. 设备就绪处理:
    加入udevadm settle确保系统完成设备枚举,解决脚本执行过早导致的"无法打开块设备"错误,这是手动挂载可行但脚本失败的常见原因。

  2. 避免重复挂载:
    用关联数组PROCESSED_SANS跟踪已处理的SAN标识,一旦处理过同SAN的首个匹配项,后续同SAN设备直接跳过。

  3. 可靠挂载方式:
    使用PARTLABEL=$partlabel作为挂载源,而非/dev/$devname,避免设备名(如sdb1、sdc1)随重启变化导致的挂载失败。

  4. 变量解析处理:
    所有变量引用均用双引号包裹,避免空格或特殊字符导致的解析异常;通过basename正确提取目录名,避免路径干扰。


登录前执行配置

方法1:使用rc.local(适用于支持sysvinit兼容的系统)

  1. 在/etc/rc.local的exit 0前添加:
    /usr/local/bin/mount_san_volumes.sh
    
  2. 赋予rc.local执行权限:
    chmod +x /etc/rc.local
    

方法2:使用systemd服务(适用于systemd系统)

  1. 创建/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
    
  2. 启用并启动服务:
    systemctl daemon-reload
    systemctl enable --now mount-san-volumes.service
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:55:37