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 "=== 所有操作都完成啦 ==="
关键细节说明
配对服务器与UUID:
paste命令会把servernames和uuids的对应行合并成一行,比如第一行就是SERVER1 VDIVUIFDVNFDHYJ,然后用while read -r server uuid读取,完美保证每台服务器对应正确的UUID,不会像原脚本那样乱序。实时CEPH状态检查:
封装了两个函数来检查CEPH状态,每次循环都会重新执行sudo ceph -s,这样CEPH状态变化时脚本能及时感知,不会一直执行旧状态的逻辑。逐对顺序执行:
处理完SERVER1的关机、检查、等待所有操作后,才会进入SERVER2的处理流程,完全符合你“完成当前对再处理下一对”的需求。避免无限循环:
每个阶段的循环末尾都会再次检查CEPH状态,如果状态变了就跳出循环,不会让脚本一直重复跑。代码维护性:
用函数封装状态检查,添加了清晰的日志输出,以后改逻辑或者加功能都更方便。
额外小建议
- 如果你需要检查特定数量的OSD在线(比如必须4个),可以把
check_ceph_osds_up里的grep改成grep -q 'osds: 4 up',精准匹配数量。 - 可以加个错误处理,比如如果找不到
servernames或者uuids文件,直接输出错误然后退出脚本。 - 长时间运行的脚本建议加日志,比如把所有输出重定向到日志文件:
>> operation.log 2>&1,方便后续排查问题。
内容的提问来源于stack exchange,提问作者Raz Maabari
相关产品推荐
相关产品推荐

