21

Is there a better way to run a shell task in a Jenkins 2.0 pipeline and then return the stdout of the command. The only way I can get this to work is to pipe the output of the command to a file and then read the file in to a variable.

sh('git config --get remote.origin.url > GIT_URL')
def stdout = readFile('GIT_URL').trim()

This seems like a really bad way to return the output. I was hoping I could do something like:

def stdout = sh('git config --get remote.origin.url').stdout

or

def exitcode = sh('git config --get remote.origin.url').exitcode

Is this possible?

CSchulz
  • 10,882
  • 11
  • 60
  • 114
user6253266
  • 563
  • 2
  • 5
  • 7
  • Possible duplicate of [How to do I get the output of a shell command executed using into a variable from Jenkinsfile (groovy)?](http://stackoverflow.com/questions/36547680/how-to-do-i-get-the-output-of-a-shell-command-executed-using-into-a-variable-fro) – Krzysztof Krasoń May 07 '16 at 09:03

2 Answers2

22

Yes as luka5z mentioned, version 2.4 of Pipeline Nodes and Processes Plugin now supports this kind of stuff:

def stdout = sh(script: 'git config --get remote.origin.url', returnStdout: true)
println stdout

def retstat = sh(script: 'git config --get remote.origin.url', returnStatus: true)
println retstat

Seems if you try to return both in the same script, returnStatus will overwrite returnStdout which is a bit unfortunate.

You can read more in the official documentation here

Edit: Furthermore, it allows you finer grained control over failed/unstable build statuses too. You can see an example in my comment here

Community
  • 1
  • 1
philbert
  • 478
  • 4
  • 15
  • 3
    Can we use them together ? catch returnStdout in a variable and returnStatus in an other ? because it is not cool to repeat the sh script twice – sirineBEJI Jun 26 '18 at 13:54
  • @codeGeass How is this supposed to work? A function has exactly _one_ return value (i.e. _one_ memory place for its return value on the stack) and that's why there's also just one assignment to one variable. See also "[_In mathematics, a function is a binary relation_](https://en.wikipedia.org/wiki/Function_(mathematics))". If you want return both (or even more, like an error msg) you have to use a complex string: CSV, JSON, XML, ... – Gerold Broser Aug 28 '21 at 17:20
  • 1
    @codeGeass See how it works at [How to return either stdout or stderr together with the status from a Jenkins Pipeline sh script step](https://stackoverflow.com/q/68967642/1744774). – Gerold Broser Aug 28 '21 at 19:45
  • I was thinking about a return output with multiples entries like map.. but now (after 4 years) I know that jenkins does not allow this :) – sirineBEJI Sep 03 '21 at 13:53
20

Update

Since 6/2016 JENKINS-26133 is officially marked as Resolved. Therefore, before trying below workarounds, first try supported implementation for sh/bat which makes it possible to use returnStdout and returnStatus parameters.

Workarounds

Unfortunately this feature is still unsupported and missing. For more information please refer to official ticket:

JENKINS-26133 Shell script taking/returning output/status Status: Assignee: Priority: Resolution: Open Jesse Glick Major Unresolved


Description

Currently sh has no meaningful return value, and throws an exception if the exit status is not zero. Would be nice to have an option to have it return the exit code (zero or not) as an integer value:

def r = sh script: 'someCommand', returnStatus: true

Current workaround:

sh 'someCommand; echo $? > status' 
def r = readFile('status').trim()

Or to have it return its standard output (akin to shell backticks):

def lines = sh(script: 'dumpStuff.sh', returnStdout: true).split("\r?\n")

Workaround:

sh 'dumpStuff.sh > result'
def lines = readFile('result').split("\r?\n")

Or to have it take something on standard input:

sh script: 'loadStuff.sh', stdin: someText

Workaround:

writeFile file: 'input', text: someText >     sh 'loadStuff.sh < input'

Probably requires some API changes in durable-task.

luka5z
  • 7,525
  • 6
  • 29
  • 52