为何Groovy中字符串嵌套引号执行命令失效,数组传参却可行?
你在终端中可以正常执行的AWS CLI命令如下:
aws dynamodb get-item --output text --table-name tableName \ --key='{"partitopnKey":{"S":"partitionKeyValue"}}' --query "Item.[someOtherValue]"
但将该命令写入Groovy管道的字符串变量执行时,无论调整引号组合、转义方式、变量定义形式还是--key的赋值格式,都无法正常运行;改用字符串数组形式传参后则成功执行:
def nameOfVar = ["aws", "dynamodb", "get-item", "--output", "text", "--table-name", "tableName", "--key", "{\"partitopnKey\":{\"S\":\"${partitionKeyValue}\"}}", "--query", "Item.[someOtherValue]"]
核心原因在于Groovy执行命令时,字符串形式与数组形式的参数处理逻辑完全不同:
shell解析与转义冲突
终端里的引号是给shell用来识别参数边界的,shell会自动去掉外层引号,把内部内容作为完整参数传给AWS CLI。但Groovy中直接用字符串传递命令时,整个字符串会被交给系统shell解析,此时Groovy的转义规则和shell的解析规则会发生冲突——比如你为了让Groovy识别JSON里的引号而添加的转义符,到了shell层面可能被错误处理,导致最终传给AWS CLI的--key参数不是合法的JSON格式,或者参数被意外拆分。数组形式跳过shell解析,参数边界绝对清晰
Groovy中用字符串数组传参时,数组的每个元素会被直接作为独立参数传给执行函数(如execute()),完全跳过了系统shell的参数拆分逻辑。--key对应的JSON字符串作为一个单独的数组元素,完整且无修改地传递给AWS CLI,不会出现因为空格、引号导致的参数拆分错误,AWS CLI能准确识别到合法的JSON格式参数。变量插值的可靠性差异
数组形式中使用${partitionKeyValue}插值时,Groovy会直接将变量值替换到字符串中,最终作为一个完整的参数元素传递,哪怕变量值包含特殊字符,也不会破坏参数结构。而字符串形式中插值后,变量值会被包含在整个命令字符串里,交给shell解析时,若变量值有空格、引号等特殊字符,会直接打乱shell的参数拆分逻辑,导致命令执行失败。
内容的提问来源于stack exchange,提问作者Uberhumus

