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

Shell脚本IF条件比较字符串异常排查求助

Shell脚本字符串匹配失败问题解决

问题详情

我在Shell脚本中通过IF条件比较字符串时未得到预期结果。我的应用有三类Eventing-Function运行日志,已将日志内容赋值给executionstatus变量,日志内容如下:

"composite_status": "deployed",
   "name": "Eventing-Function",
   "num_bootstrapping_nodes": 0,
   "num_deployed_nodes": 5,
   "deployment_status": true,
   "processing_status": true,
   "redeploy_required": false 

"composite_status": "deployed",
   "name": "Eventing-Function-on-expiry",
   "num_bootstrapping_nodes": 0,
   "num_deployed_nodes": 5,
   "deployment_status": true,
   "processing_status": true,
   "redeploy_required": false
 
"composite_status": "deployed",
   "name": "Eventing-Function-dev",
   "num_bootstrapping_nodes": 0,
   "num_deployed_nodes": 5,
   "deployment_status": true,
   "processing_status": true,
   "redeploy_required": false 

我把其中的deployed提取出来赋值给status变量,名称赋值给name变量,通过for循环遍历5个节点,需求是检查这三类Eventing-Function的状态是否均为deployed,否则触发邮件告警。但比较$status和$cbstatus时匹配失败,调试输出如下:

+ '[' 'deployed deployed deployed ' == 'deployed deployed deployed' ']'
+ echo 'status is not deployed at ' $url

明显是status变量末尾多了一个空格导致匹配失败,我的脚本代码如下:

for url in "${uat_urls[@]}"
do
    executionstatus=$(curl -sX GET -u ${admin}:${password} 'http://'${url}':8009/api/v1/status')
    status=$(echo $executionstatus | grep -o '"composite_status": "[^"]*'| grep -o '[^"]*$' |tr '\n' ' ')
    name=$(echo $executionstatus | grep -o '"name": "[^"]*'| grep -o '[^"]*$')

    cbstatus=$(printf "deployed deployed deployed")
    echo $status
    echo $cbstatus
    if [ "${status}" != "${cbstatus}" ]; then
        echo "status is not deployed at " $url  >> status.txt
        # mail that the eventing function is not deployed
        echo "$(<status.txt )" | mailx -r "xyz.testcom" -s "FE CB AS eventing service status" $mail_me
        rm status.txt
    else
       echo "status is not deployed at " $url >> status.txt
    fi
done

解决方案

方法1:直接去除status变量末尾空格

在提取status后,用Shell内置语法或sed去掉末尾多余空格:

# 方式A:用sed去除末尾所有空白字符
status=$(echo $executionstatus | grep -o '"composite_status": "[^"]*'| grep -o '[^"]*$' |tr '\n' ' ' | sed 's/[[:space:]]*$//')

# 方式B:用Shell参数扩展去除最后一个空格
status=$(echo $executionstatus | grep -o '"composite_status": "[^"]*'| grep -o '[^"]*$' |tr '\n' ' ')
status=${status% }

方法2:改用数组存储状态(更健壮)

用空格拼接字符串容易出问题,直接将每个状态存入数组,逐个校验是否为deployed:

for url in "${uat_urls[@]}"
do
    executionstatus=$(curl -sX GET -u ${admin}:${password} 'http://'${url}':8009/api/v1/status')
    # 将提取到的每个状态存入数组
    read -ra status_array <<< "$(echo $executionstatus | grep -o '"composite_status": "[^"]*'| grep -o '[^"]*$')"
    
    # 检查所有状态是否都是deployed
    all_deployed=true
    for s in "${status_array[@]}"; do
        if [ "$s" != "deployed" ]; then
            all_deployed=false
            break
        fi
    done

    if [ "$all_deployed" = false ]; then
        echo "status is not deployed at $url" >> status.txt
        echo "$(<status.txt)" | mailx -r "xyz.testcom" -s "FE CB AS eventing service status" $mail_me
        rm status.txt
    else
        echo "all eventing functions are deployed at $url" >> status.txt
    fi
done

方法3:用jq解析JSON(推荐)

如果接口返回的是标准JSON格式,用专门的JSON解析工具jq提取状态,避免正则匹配的各种问题:

for url in "${uat_urls[@]}"
do
    # 用jq提取每个对象的composite_status,存入数组
    status_array=($(curl -sX GET -u ${admin}:${password} 'http://'${url}':8009/api/v1/status' | jq -r '.composite_status'))
    
    all_deployed=true
    for s in "${status_array[@]}"; do
        if [ "$s" != "deployed" ]; then
            all_deployed=false
            break
        fi
    done

    if [ "$all_deployed" = false ]; then
        echo "status is not deployed at $url" >> status.txt
        echo "$(<status.txt)" | mailx -r "xyz.testcom" -s "FE CB AS eventing service status" $mail_me
        rm status.txt
    else
        echo "all eventing functions are deployed at $url" >> status.txt
    fi
done

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 13:05:22