Jenkins Groovy脚本执行Shell命令

4
我正在使用Groovy脚本计算构建持续时间,并将指标发布到Hosted Graphite。从命令行执行以下curl命令将产生预期效果:
echo {someMetricHere} | nc carbon.hostedgraphite.com 2003

然而,在我的Groovy脚本中,生成指标的最后一步是运行以下命令:

"echo "+ metric +" | nc carbon.hostedgraphite.com 2003".execute()

它返回:

捕获异常:java.io.IOException: Cannot run program "|": error=20, Not a directory java.io.IOException: Cannot run program "|": error=20, Not a directory at hudson8814765985646265134.run(hudson8814765985646265134.groovy:27) 造成原因:java.io.IOException: error=20, 不是一个目录 ... 1 more

我认为该命令不理解命令中的“|”部分,有建议如何修复此脚本以运行预期的bash吗?我认为可以在工作区创建.sh文件,但不确定如何操作。

对于那些想要查看完整脚本的人,请使用Pastebin链接:https://pastebin.com/izaXVucF

干杯 :)


管道符号 | 是 shell(bash)的一个特性。因此,如果您想使用它,请使用您想要的命令和管道启动 shell... - daggett
我原本以为可以通过Groovy执行shell命令,我没有问题使用这个命令运行单独的shell步骤(我可能更喜欢这种方式),但是我不知道如何将这个Groovy脚本的输出传递到那个shell步骤中。 - WillBroadbent
5个回答

14

要使用管道符号|,请尝试以下代码:

// this command line definitely works under linux:
def cmd = ['/bin/sh',  '-c',  'echo "12345" | grep "23"']
// this one should work for you:
// def cmd = ['/bin/sh',  '-c',  'echo "${metric}" | nc carbon.hostedgraphite.com 2003']

cmd.execute().with{
    def output = new StringWriter()
    def error = new StringWriter()
    //wait for process ended and catch stderr and stdout.
    it.waitForProcessOutput(output, error)
    //check there is no error
    println "error=$error"
    println "output=$output"
    println "code=${it.exitValue()}"
}

输出结果:

error=
output=12345
code=0

嗨,Daggett,我尝试了一下,但不幸的是没有成功 :/ 从服务器运行完全相同的命令没有错误,但似乎并没有以相同的方式调用Echo和NC命令。不确定如何调试这个问题,所以可能需要找到不同的方法。 - WillBroadbent
@WillBroadbent:我现在遇到了类似的问题,你解决了吗? - mmoossen
@mmoossen,我已经用更简单的例子更新了答案。请检查它是否适用于您。 - daggett
当Jenkins托管在Windows上时,是否知道有类似的替代方案? - dtmland
['cmd','/c','echo 12345 | ...'] - daggett
显示剩余2条评论

2
我认为你的拼接有问题。
以下代码应该可以正常工作:
"echo ${metric} | nc carbon.hostedgraphite.com 2003".execute()

1

一个更简单的方法是使用Jenkins Job DSL。它具有可以在给定步骤内发出的shell命令。例如:

// execute echo command
job('example-1') {
    steps {
        shell('echo Hello World!')
    }
}

// read file from workspace
job('example-2') {
    steps {
        shell(readFileFromWorkspace('build.sh'))
    }
}

你可以在这里找到参考资料。

1
除了daggett提供的出色(虽然复杂)的答案之外,在Jenkins脚本界面上,这里有一种简单(易于记忆和输入)的方法:
['/bin/sh', '-c', 'env | grep JAVA_OPTS'].execute().text

脚本化流水线就像 sh 'env | grep JAVA_OPTS'


0

如果你需要将一个变量传递给Groovy脚本,可以使用${variableName}。双引号不会像你想象的那样被解释,每个编译器都以一种奇怪的方式处理它。

在你的情况下,下面这行代码应该能够帮助你实现你想要的功能:

sh "echo ${metric} | nc carbon.hostedgraphite.com 2003"

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