【问题标题】:Jenkins Groovy script to execute shell commandsJenkins Groovy 脚本执行 shell 命令
【发布时间】:2017-09-29 08:11:46
【问题描述】:

我正在使用一个 groovy 脚本来计算我的构建持续时间并将一个指标发布到 Hosted Graphite,从命令行将产生以下 curl 并产生预期效果:

echo {someMetricHere} | nc carbon.hostedgraphite.com 2003

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

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

它的回归:

捕获:java.io.IOException:无法运行程序“|”:错误=20,不是目录 java.io.IOException:无法运行程序“|”:错误=20,不是目录 在 hudson8814765985646265134.run(hudson8814765985646265134.groovy:27) 引起:java.io.IOException: error=20, Not a directory ... 1 更多

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

Pastebin 适合想要查看完整脚本的用户:https://pastebin.com/izaXVucF

干杯:)

【问题讨论】:

  • 管道| 是shell (bash) 的一个特性。所以如果你想用你想要的命令和管道启动 shell...
  • 我的印象是我可以通过 groovy 执行 shell 命令,使用此命令运行单独的 shell 步骤没有问题(我可能更喜欢它)但是我不知道如何将此 groovy 脚本的输出传递到该 shell 步骤。

标签: bash shell jenkins groovy graphite


【解决方案1】:

使用管道|试试这个代码:

// 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

【讨论】:

  • Cheers Daggett,我试了一下,但不幸的是没有运气:/ 从服务器运行完全相同的命令不会返回任何错误,但似乎实际上并没有以相同的方式调用 Echo 和 NC 命令.不确定如何调试它,因此可能需要找到不同的方法
  • 你在 jenkins-pipeline 中吗?你有输出错误吗?尝试一些简单的事情,例如:echo 123 | grep 123
  • @WillBroadbent:我现在遇到了类似的问题,你能解决吗?
  • @mmoossen,我用更简单的例子更新了答案。请检查它是否适合您。
  • 作为重要的旁注请注意def cmd = '/bin/sh -c echo "12345" | grep "23"' 不会工作....
【解决方案2】:

我认为你所做的连接有问题。

这段代码应该可以工作:

"echo ${metric} | nc carbon.hostedgraphite.com 2003".execute()

【讨论】:

    【解决方案3】:

    实现此目的的更简单方法是使用Jenkins Job DSL。它具有一个shell 命令,可以从给定的step 中发出。例如:

    // execute echo command
    job('example-1') {
        steps {
            shell('echo Hello World!')
        }
    }
    
    // read file from workspace
    job('example-2') {
        steps {
            shell(readFileFromWorkspace('build.sh'))
        }
    }
    

    您可以找到参考here

    【讨论】:

      【解决方案4】:

      如果您必须将变量传递给 groovy 脚本,请使用 ${variableName}。双引号不会像你想象的那样被解释,每个编译器都以一种奇怪的方式对待它。

      在您的情况下,以下行应该有助于做您想做的事情:

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

      【讨论】: