在命令字符串中带引号的 Groovy 外部命令

Jam*_*esE 2 java groovy

这与Groovy 使用命令中的引号执行外部 RTC 命令有关。我在组件列表中的引号被 shell 解释为命令本身的一部分。

这是应该运行的命令(如果直接在命令行上运行也是如此):

scm workspace add-components test-workspace -s test-stream "test1" "test 2" -r url
Run Code Online (Sandbox Code Playgroud)

问题似乎来自“test1”“test2”

这作为 ArrayList 传递到命令方法中,然后转换为字符串:

void addComponents(String repository, String name, String flowTarget, ArrayList components) {
    String compStr = components.toString().replace("[", "'").replace("]", "'").replace(", ", "' '")
    println compStr
    String cmd = "scm workspace add-components ${name} -s ${flowTarget} ${compStr} -r ${repository}"
    println cmd

    def proc = ["scm", "workspace","add-components", "${name}","-s", "${flowTarget}","${compStr}","-r", "${repository}"].execute()

    //def proc = cmd.execute()
    proc.waitFor()

    getReturnMsg(proc)
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试了直字符串以及将命令放入数组并将其传递给执行。

Unmatched component ""test1" "test 2""
Run Code Online (Sandbox Code Playgroud)

从错误看来,它不是在寻找组件 test1,而是在寻找“test1 test2”。

基于此,我似乎需要将“test1”和“test 2”分离到数组中的单独元素中,如下所示:

def proc = ["scm", "workspace", "add-components","Jenkins_${name}_${workspaceId}_Workspace","-s",flowTarget,"test1","test 2","-r",repository].execute()
Run Code Online (Sandbox Code Playgroud)

事实上,如果我像这样将组件列表硬编码到命令数组中,它确实可以工作。

问题是组件列表的长度因项目而异。有没有办法像这样构造一个可变长度的命令数组?组件列表来自具有如下结构的 JSON 文件:

{
    "project": [
        {
            "name": "Project1",
            "components": [
                "component1",
                "component 2",
                "component 3"
            ]
        },
        {
            "name": "Project2",
            "components": [
                "component1",
                "component 4",
                "component 5",
                "component6"
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*ser 5

GroovyString#execute()和 JavaRuntime#exec(String)使用简单new java.util.StringTokenizer()的分割参数。不涉及外壳,因此拆分规则不同(并且更原始)。传递列表/数组更安全,在这种情况下,拆分是显式的,并且参数将按原样传递给进程。这意味着您需要确保参数不包含任何不应传递给进程的字符(例如引号)。