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

BASH环境下基于服务器与UUID成对的多变量条件循环实现方案咨询

解决BASH中服务器与UUID配对遍历的循环问题

Hey,看起来你需要实现一个按顺序处理服务器-UUID配对的BASH脚本,而且所有操作得等CEPH集群满足特定状态才会执行,还要每对处理完再搞下一对。原脚本的主要问题是没做好服务器和UUID的一一对应,而且CEPH状态只读了一次,没法实时响应状态变化。我来给你优化下方案:

核心改进点

  • 用paste命令把服务器名和UUID文件按行配对,确保每一组对应关系精准,不会乱序
  • 实时检查CEPH状态,而不是只读取一次,这样状态变化时脚本能及时响应
  • 用while read循环逐行处理配对数据,保证先处理完当前服务器的所有操作,再轮到下一个
  • 删掉没必要的临时文件,直接用命令替换获取CEPH状态,简化代码

完整优化后的脚本

#!/bin/bash

# 先定义好文件路径,方便后续修改
SERVER_FILE="info/servernames"
UUID_FILE="info/uuids"
AUTH=$(cat info/token)
SPT=$(cat info/SPT)

# 封装CEPH状态检查的函数,用起来更方便
check_ceph_osds_up() {
    # 检查CEPH是否有OSD处于up状态,返回0表示满足条件,1表示不满足
    sudo ceph -s | grep -q 'osds: [0-9]* up'
}

check_ceph_osds_down() {
    # 反过来,检查OSD是否不满足up状态
    ! check_ceph_osds_up
}

# 第一阶段:CEPH满足条件时,逐对处理服务器关机和SPT应用
echo "=== 等待CEPH满足状态,开始处理服务器 ==="
while check_ceph_osds_up; do
    # 把服务器名和UUID按行配对,逐行读取每一组
    paste "$SERVER_FILE" "$UUID_FILE" | while read -r server uuid; do
        echo "===== 开始处理服务器: $server (UUID: $uuid) ====="
        
        # 这里放你的关机操作逻辑
        echo "TOKEN: ${AUTH}"
        echo "服务器名称: $server"
        echo "UUID: $uuid"
        echo "SPT: $SPT"
        sleep 2s
        
        echo "正在给 $server 应用SPT..."
        echo "TOKEN: $AUTH"
        echo "NAME: $server"
        echo "UUID: $uuid"
        
        # 检查服务器是否成功关机
        ping -c 1 "$server" >> /dev/null 2>&1
        if [ $? -ne 0 ]; then
            echo "$server 已经关机成功啦"
        else
            echo "$server 关机失败,还在线呢"
        fi
        
        echo "===== $server 处理完成,等待2分钟 ====="
        sleep 2m
    done
    
    # 每次处理完所有配对后,再检查一次CEPH状态,避免无限循环
    if ! check_ceph_osds_up; then
        break
    fi
done

# 第二阶段:CEPH状态变了,再次逐对应用SPT
echo "=== CEPH状态变化,开始再次应用SPT ==="
while check_ceph_osds_down; do
    paste "$SERVER_FILE" "$UUID_FILE" | while read -r server uuid; do
        echo "===== 再次给 $server (UUID: $uuid) 应用SPT ====="
        echo "TOKEN: ${AUTH}"
        echo "服务器名称: $server"
        echo "UUID: $uuid"
        sleep 5s
    done
    
    # CEPH状态恢复正常就退出循环
    if check_ceph_osds_up; then
        break
    fi
done

echo "=== 所有操作都完成啦 ==="

关键细节说明

  1. 配对服务器与UUID:
    paste命令会把servernames和uuids的对应行合并成一行,比如第一行就是SERVER1 VDIVUIFDVNFDHYJ,然后用while read -r server uuid读取,完美保证每台服务器对应正确的UUID,不会像原脚本那样乱序。

  2. 实时CEPH状态检查:
    封装了两个函数来检查CEPH状态,每次循环都会重新执行sudo ceph -s,这样CEPH状态变化时脚本能及时感知,不会一直执行旧状态的逻辑。

  3. 逐对顺序执行:
    处理完SERVER1的关机、检查、等待所有操作后,才会进入SERVER2的处理流程,完全符合你“完成当前对再处理下一对”的需求。

  4. 避免无限循环:
    每个阶段的循环末尾都会再次检查CEPH状态,如果状态变了就跳出循环,不会让脚本一直重复跑。

  5. 代码维护性:
    用函数封装状态检查,添加了清晰的日志输出,以后改逻辑或者加功能都更方便。

额外小建议

  • 如果你需要检查特定数量的OSD在线(比如必须4个),可以把check_ceph_osds_up里的grep改成grep -q 'osds: 4 up',精准匹配数量。
  • 可以加个错误处理,比如如果找不到servernames或者uuids文件,直接输出错误然后退出脚本。
  • 长时间运行的脚本建议加日志,比如把所有输出重定向到日志文件:>> operation.log 2>&1,方便后续排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 22:27:30