Keywords: Jenkins Pipeline | sh Command | Standard Output Capture | returnStdout Parameter | Automated Build
Abstract: This technical article provides an in-depth exploration of capturing standard output (stdout) when using the sh DSL command in Jenkins pipelines. By analyzing common problem scenarios, it details the working mechanism, syntax structure, and practical applications of the returnStdout parameter, enabling developers to correctly obtain command execution results rather than just exit codes. The article also discusses related best practices and considerations, offering technical guidance for building more intelligent automation workflows.
Problem Context and Common Misconceptions
In Jenkins pipeline development, developers often need to execute shell commands and capture their output. A typical erroneous example is as follows:
var output = sh "echo foo";
echo "output=$output";After executing this code, the variable output will have the value 0, which is the command's exit status code, not the expected standard output content foo. This occurs because, by default, the sh step returns the command's exit code, aligning with conventional Unix/Linux command execution behavior. However, this approach lacks flexibility in scenarios requiring processing of command output content.
Solution: The returnStdout Parameter
Starting from Jenkins 2.0, the sh step introduced the returnStdout parameter specifically designed to capture a command's standard output. The official documentation clearly states that when set to true, the step returns all content written to stdout during command execution, instead of the exit code.
The basic syntax structure is as follows:
def output = sh(returnStdout: true, script: 'your-shell-command')Several key points should be noted here:
returnStdoutmust be explicitly set to the boolean valuetrue- The
scriptparameter contains the shell command to execute - The return value is a string containing all standard output from the command
Practical Application Examples
The following is a complete code example demonstrating how to use the returnStdout parameter in real-world scenarios:
// Execute after checking out source code on the agent
// Ensure a git executable is available in the system
def gitCommit = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
def shortCommit = gitCommit.take(6)
// Output results
echo "Full commit hash: ${gitCommit}"
echo "Short commit identifier: ${shortCommit}"In this example:
- The
git rev-parse HEADcommand returns the latest commit hash of the current branch - The
.trim()method removes leading and trailing whitespace characters (including newlines) from the output string .take(6)extracts the first six characters as a short commit identifier, commonly used in scenarios like chat notifications
Through this approach, developers can easily integrate command output into pipeline logic decisions, variable assignments, or subsequent processing steps.
Technical Details and Considerations
When using the returnStdout parameter, the following technical details should be considered:
- Output Processing: Shell command output typically includes trailing newline characters, requiring cleanup using methods like
.trim() - Error Handling: When a command fails (returns a non-zero exit code), the step throws an exception, necessitating appropriate exception handling mechanisms
- Performance Considerations: For commands generating substantial output, memory usage and performance impacts should be evaluated
- Compatibility: This feature requires Jenkins 2.0 or higher, with relevant plugins correctly installed
An enhanced example incorporating error handling is as follows:
try {
def output = sh(returnStdout: true, script: 'complex-command').trim()
echo "Command output: ${output}"
} catch (Exception e) {
echo "Command execution failed: ${e.message}"
currentBuild.result = 'FAILURE'
}Best Practice Recommendations
Based on practical project experience, we recommend the following best practices:
- Always perform appropriate cleaning and processing on returned strings
- Use pagination or streaming processing for commands potentially generating large outputs
- Encapsulate complex shell logic into separate script files to improve maintainability
- Establish unified coding standards within teams to ensure all developers use consistent patterns
- Regularly check for updates to Jenkins and plugins to obtain the latest feature improvements and security fixes
By correctly utilizing the returnStdout parameter, developers can build more intelligent and flexible Jenkins pipelines, enabling smooth transitions from simple command execution to complex automated workflows.