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
相关产品推荐
相关产品推荐

