Jenkins Groovy script to execute shell commands

28,250

Solution 1

to use pipe | try this code:

// 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()}"
}

the output:

error=
output=12345
code=0

Solution 2

I think something is wrong with the concatenation you did.

This code should work:

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

Solution 3

A simpler way to achieve this is to use the Jenkins Job DSL. It features a shell command that can be issued from within a given step. For example:

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

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

You can find the reference here.

Share:
28,250
WillBroadbent
Author by

WillBroadbent

Updated on January 10, 2020

Comments

  • WillBroadbent
    WillBroadbent over 4 years

    I'm using a groovy script to calculate my build duration and publish a metric to Hosted Graphite, from the command line the following curl will result with the intend effect:

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

    However in my groovy script the last step having generated a metric is to run the following:

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

    Its returning:

    Caught: 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) Caused by: java.io.IOException: error=20, Not a directory ... 1 more

    I assume the command doesn't understand the "|" part of the command, any suggestions how I can fix this script to run the intended bash? I thought it might be possible to create a .sh file in the workspace but am not sure how.

    Pastebin for those wanting to see full script: https://pastebin.com/izaXVucF

    Cheers :)

    • daggett
      daggett over 6 years
      the pipe | is a feature of shell (bash). so if you want to use it start shell with commands and pipes you want...
    • WillBroadbent
      WillBroadbent over 6 years
      I was under the impression I could execute shell commands through groovy, I've no issue running a separate shell step with this command (I'd probably prefer it) however I don't know how to pass the output from this groovy script into that shell step.
  • WillBroadbent
    WillBroadbent over 6 years
    Cheers Daggett, I gave this a go but unfortunately no luck :/ Running the exact same command from the server returns no errors but doesn't seem to actually call the Echo & NC command in the same way. Unsure how to debug this though so might need to find a different approach
  • daggett
    daggett over 6 years
    are you in jenkins-pipeline? do you have any error in output? try something simple like : echo 123 | grep 123
  • mmoossen
    mmoossen over 6 years
    @WillBroadbent: i got a similar problem now, could you solve it?
  • daggett
    daggett over 6 years
    @mmoossen, i've updated the answer with simpler example. please check if it works for you.
  • mmoossen
    mmoossen over 6 years
    as an important side note be aware that def cmd = '/bin/sh -c echo "12345" | grep "23"' wont work....
  • dtmland
    dtmland over 5 years
    Know of an equivalent when Jenkins is hosted on Windows?
  • daggett
    daggett over 5 years
    [ 'cmd', '/c', 'echo 12345 | ...' ]