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

时间:2014-05-09 17:56:40

标签: java groovy

这与Groovy execute external RTC command with quotes in the command有关。我在组件列表中放置的引号被shell解释为命令本身的一部分。

这是应该运行的命令(如果直接在命令行上运行,则执行此操作):

scm workspace add-components test-workspace -s test-stream "test1" "test 2" -r url

问题似乎来自" test1" " TEST2"

将其作为ArrayList传递给命令方法,然后转换为String:

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)
}

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

Unmatched component ""test1" "test 2""

从错误看起来,而不是寻找组件test1,它正在寻找" test1 test2"一起来。

基于此,似乎我需要分开" test1"和"测试2"进入数组中的单独元素,如下所示:

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

事实上,如果我将组件列表硬编码到这样的命令数组中,它确实有效。

问题是组件列表的长度可变,具体取决于项目。有没有办法构建这样的可变长度命令数组?组件列表来自JSON文件,其结构如下所示:

{
    "project": [
        {
            "name": "Project1",
            "components": [
                "component1",
                "component 2",
                "component 3"
            ]
        },
        {
            "name": "Project2",
            "components": [
                "component1",
                "component 4",
                "component 5",
                "component6"
            ]
        }
    ]
}

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:2)

解决方案是将每个组件(存储在单独的列表中)单独添加到命令列表中,而不是将它们组合在一起作为一个字符串:

def components = ["test1", "test 2"]

def cmd = ["scm", "workspace", "flowtarget", "test-workspace", "test-stream", "-r", url, "-C"]

for (component in components) {
    cmd.add(component)
}

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