完美运行的curl命令在groovy脚本中执行时失败

30

我在gitblit中有一个提交后钩子(一个Groovy脚本),用来调用REST端点。在这个脚本中,我执行了一个curl命令。但它似乎失败了。当从命令行执行curl命令时,它正常工作。

以下是我的Groovy脚本:

#!/usr/bin/env groovy


def repoUrl= "https://gitblit.myhost.com/git/" + repository + ".git"
json='{"repository":{"url":"'+repoUrl+'"}}'

def response = "curl -v -k -X POST -H \"Content-Type: application/json\" -d '${json}' https://username:password@anotherhost.com:9443/restendpoint".execute().text
println response 

gitblit将存储库传递给此脚本,我已经验证过了。

有人能帮帮我吗。


你能在执行前打印出 GString 以确保它生成了你期望的命令吗? - bdkosher
具体是什么失败了?您能否让您的问题更加精确明确一些? - Opal
4个回答

30

我无法使用您的示例重现问题,但我会尝试猜测:

首先,请使用列表 execute() 版本,这样您就不会遇到令牌相关的问题:

process = [ 'bash', '-c', "curl -v -k -X POST -H \"Content-Type: application/json\" -d '${json}' https://username:password@anotherhost.com:9443/restendpoint" ].execute()

其次,从进程中同时读取错误和输出:

Second, read both error and output from the process:

process.waitFor()
println process.err.text
println process.text

err 可能会显示发生了什么错误


1
谢谢。我已经搜索了几个小时,但是你的解决方案对我很有用。为什么必须使用列表版本而不是常规字符串? - The Unknown Dev
@Jamil,我猜这是因为运行时执行可以正确分离参数/命令和转义,否则可能会产生歧义。 - Will
如果有人感兴趣,这里有一个简短的关于分离参数的解释:http://groovy.codehaus.org/Executing+External+Processes+From+Groovy。 - The Unknown Dev
3
第一个代码块中的.text是错误的,对吗? - crusy
我们如何从Groovy execute方法中检索HTTP代码? - nilesh1212

24

我能够通过将curl命令中的所有字符串都传递到数组中来使它工作。以下是我的做法:

def response = ["curl", "-k", "-X", "POST", "-H", "Content-Type: application/json", "-d", "${json}", "https://username:password@myhost.com:9443/restendpoint"].execute().text

0
为了避免“永远运行”的进程(当输出超过4096个字节时,在某些Windows环境下会发生这种情况),请向ByteArrayOutputStream添加初始大小。
def initialSize = 4096
def out = new ByteArrayOutputStream(initialSize)
def err = new ByteArrayOutputStream(initialSize)
def proc = command.execute()
proc.consumeProcessOutput(out, err)
proc.waitFor()

1
很难看出这个回答真正回答了这里提出的问题... - Andrew Barber
@AndrewBarber 不这样做会导致进程挂起。提问者没有说明命令失败的原因,所以猜测是合理的,而且我们无论如何都被困在猜测中。 - tsiki
我正在谷歌搜索如何解决一个“永远运行”的进程问题(非Windows),因为这是我找到的与之相关的第一个帖子,所以我想说感谢您的发布。尽管它与OP的问题不太相关,但我认为这将引导我走向解决我的问题的道路,所以谢谢! - David Farrell

0
在 Curl Post 中,使用 In-F 选项时,需要用双引号将整个参数包裹起来。别忘了转义双引号以正确使用语法。 以下是示例:
def response = "curl -u admin:admin -F\"jcr:content/par/address/address1=2/3 Market Place\" http://localhost:4502/content/datasource/branches".execute().text

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接