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

Jenkins Pipeline脚本变量报错:--topic ${TOPIC}语法非法

解决Jenkins Pipeline中Kafka Topic分区修改的变量解析错误

问题背景

构建用于修改Kafka Topic分区数的Jenkins Pipeline时,需要先获取Topic当前分区数,以此判断是否执行更新操作。但脚本执行时出现变量解析错误,报错指向--topic ${TOPIC},即便用{}包裹变量仍无法解决。

报错信息

WorkflowScript: 32: illegal string body character after dollar sign;
   solution: either escape a literal dollar sign "\$5" or bracket the value expression "${5}" @ line 32, column 36.
                       --topic ${TOPIC} | head -1)

原Pipeline代码片段

script {
                    sh """
                    if [ -n "\$(printf '%s\n' ${NUM_PARTITIONS} | sed 's/[0-9]//g')" ]; then
                      echo 'Num partitions is not numeric'
                      exit 1 
                    fi
                    """
                    
                    sh """
                    desc=\$(kafka-topics.sh \
                    --bootstrap-server ${KAFKA_SERVERS} \
                    --command-config sasl.properties \
                    --describe \
                    --topic ${TOPIC} | head -1)
                    
                    if [ \$? -ne 0 ]; then
                      echo 'describe failed'
                      exit 1
                    fi
                    
                    np=\$(echo desc | gawk 'match($0, /PartitionCount:\s*([[:digit:]]*)\s*/, a) {print a[1]}')
                    
                    if [ ${NUM_PARTITIONS} -le np ]; then
                        echo 'num partitions <= configured partitions.  alter skipped'
                    else
                      kafka-topics.sh \
                      --bootstrap-server ${KAFKA_SERVERS} \
                      --command-config sasl.properties \
                      --alter \
                      --topic ${TOPIC} \
                      --partitions ${NUM_PARTITIONS}
                    fi
                    """
}

错误原因

报错的根源并非${TOPIC},而是脚本中未转义的shell特殊符号和变量:
Jenkins Pipeline的三重引号(""" "")会优先让Groovy解析其中的$表达式。当Groovy遇到$0(gawk中的匹配对象)、未转义的$?、$desc、$np时,会将其视为Groovy变量,但这些符号在Groovy中无合法定义,从而触发语法错误。

修正方案

区分Groovy变量和shell变量,对shell自身的$符号进行转义:

  • 需要Groovy替换的变量(如${TOPIC}、${KAFKA_SERVERS})保持原样
  • shell的特殊符号($?)、shell变量($desc、$np)、gawk中的$0需转义为\$?、\$desc、\$np、\$0
  • 多行shell命令的续行符\需转义为\\,避免被Groovy解析为换行符

修正后的代码

script {
    sh """
    if [ -n "\$(printf '%s\n' ${NUM_PARTITIONS} | sed 's/[0-9]//g')" ]; then
      echo 'Num partitions is not numeric'
      exit 1 
    fi
    """
    
    sh """
    desc=\$(kafka-topics.sh \\
    --bootstrap-server ${KAFKA_SERVERS} \\
    --command-config sasl.properties \\
    --describe \\
    --topic ${TOPIC} | head -1)
    
    if [ \\$? -ne 0 ]; then
      echo 'describe failed'
      exit 1
    fi
    
    np=\$(echo \\$desc | gawk 'match(\\$0, /PartitionCount:\\s*([[:digit:]]*)\\s*/, a) {print a[1]}')
    
    if [ ${NUM_PARTITIONS} -le \\$np ]; then
        echo 'num partitions <= configured partitions.  alter skipped'
    else
      kafka-topics.sh \\
      --bootstrap-server ${KAFKA_SERVERS} \\
      --command-config sasl.properties \\
      --alter \\
      --topic ${TOPIC} \\
      --partitions ${NUM_PARTITIONS}
    fi
    """
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:10:50