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

如何用xmlstarlet结合Shell脚本在policy.xml指定节点插入限流规则?

问题分析

当前存在几个核心问题:

  1. XMLStarlet命令错误:路径拼写错误(ibound应为inbound),未准确保留插入节点的特殊字符与格式,也未指定插入位置为<base />之后。
  2. Shell变量引号问题:ipfilter变量包含嵌套双引号,直接赋值会导致语法错误。
  3. 脚本逻辑瑕疵:循环条件判断有误,且每次编辑都从原始文件重新生成,未增量修改目标文件。

解决方案

1. 修正XMLStarlet命令

要在指定节点的<base />之后插入限流规则,需使用--insert参数定位到<base />标签,然后插入新节点。同时用-L选项直接修改目标文件(避免重复生成新文件)。

正确命令示例(以inbound为例):

xmlstarlet edit -L \
  --insert "//policies/inbound/base" --type elem --name "rate-limit-by-key" \
  --attr calls "xxx" \
  --attr renewal-period "xx" \
  --attr counter-key '@(Regex.Match(context.x.y.GetValueOrDefault("xxxxxxx",""), @"^[.x-y]*")?.Value)' \
  custompolicy.xml

2. 修正Shell变量定义

使用单引号包裹整个节点字符串,避免嵌套双引号导致的语法错误:

ipfilter='<rate-limit-by-key calls="xxx" renewal-period="xx" counter-key="@(Regex.Match(context.x.y.GetValueOrDefault("xxxxxxx",""), @"^[.x-y]*")?.Value)" />'

3. 调整Shell脚本逻辑

  • 先复制原始文件到目标文件,后续编辑均基于该目标文件增量修改。
  • 修正循环条件判断,正确匹配inbound/backend/outbound。
  • 补全缺失的循环闭合语句。

完整调整后的脚本:

#!/bin/bash
################Variables##################
source parse_yaml.sh
eval $(parse_yaml input2.yaml policy)

# 正确定义限流节点字符串(单引号包裹避免引号冲突)
ipfilter='<rate-limit-by-key calls="xxx" renewal-period="xx" counter-key="@(Regex.Match(context.x.y.GetValueOrDefault("xxxxxxx",""), @"^[.x-y]*")?.Value)" />'

echo ".............Eval Result..............................."
for f in $policy_ ; do eval echo \$f \$${f}_ ; done
echo "............Eval Result................................"
echo " ********policy is ************ "

# 复制原始XML文件到目标文件,避免破坏原文件
cp policy.xml custompolicy.xml

for f in $policy_ ; do
  if [[ $(eval echo \$${f}_name) == "ipfilter" ]]; then
    echo " given policy name is ipfilter "
    if [[ $(eval echo \$${f}_scope) == "api" ]]; then
      echo "decided the scope of Ipfilter policy as api "
    fi
    for g in $(eval echo \$${f}_apis_); do
      echo " this policy will be applied to apis, $g"
      # 遍历当前API对应的session列表
      for h in $(eval echo \$${g}_session_); do
        echo " this policy will be applied to api, $g under session $h "
        # 根据session类型插入节点
        case "$h" in
          inbound|backend|outbound)
            echo "adding Ipfilter string to the $h session of xml"
            # 使用XMLStarlet在<base />之后插入节点,直接修改目标文件
            xmlstarlet edit -L \
              --insert "//policies/$h/base" --type elem --name "rate-limit-by-key" \
              --attr calls "xxx" \
              --attr renewal-period "xx" \
              --attr counter-key '@(Regex.Match(context.x.y.GetValueOrDefault("xxxxxxx",""), @"^[.x-y]*")?.Value)' \
              custompolicy.xml
            ;;
          *)
            echo "unsupported session type: $h"
            ;;
        esac
      done
    done
  fi
done

关键说明

  • --insert参数:定位到//policies/$h/base(即对应节点下的<base />标签),插入新节点作为其后续同级节点,确保位置符合要求。
  • -L选项:直接编辑目标文件,无需每次重定向到新文件,支持多次增量修改。
  • Case语句:统一处理inbound/backend/outbound三种合法类型,避免重复判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:32:05