这与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”和“test 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 回答
Groovy的
String#execute()
和Java的Runtime#exec(String)
使用简单的new java.util.StringTokenizer()
来分割参数 . 没有涉及shell,因此拆分规则不同(更原始) . 它's safer to pass a list/array, in which case the splitting is explicit, and the arguments will be passed as-is to the process. This means that you' ll需要确保将这些参数传递给进程 .解决方案是将每个组件(存储在单独的列表中)单独添加到命令列表中,而不是将它们组合在一起作为一个字符串: