如何从Jenkins Pipeline sh脚本步骤返回stdout、stderr以及执行状态?

7

提供了一个类似问题的解决方案,但仅适用于Jenkins之外的shell cmd。 - Ian W
@IanW 感谢您提供的信息。我认为 OP 的要求“_Filter stderr_”会使事情变得复杂...而且...正如您所说,这是没有 Jenkins 的。 - Gerold Broser
不。我应该吗? - Ian W
2
我不再想知道为什么有些问题会立即被downvote和关闭,而其他明显应该被downvote、关闭或删除的问题(如作业类型、没有研究、帮助台等)似乎从来没有被处理过。也许可以改变措辞,不要说自我回答,而是在这个问题的扩展中添加场景... - Ian W
2个回答

6
为了一起返回stdoutstderr以及状态,可以执行以下操作:
def runScript(command) {
    script {
        sh script: "set +x ; $command 2>&1 && echo \"status:\$?\" || echo \"status:\$?\" ; exit 0", returnStdout: true
    }
}

pipeline {
    agent any

    stages {
        stage('more values from sh') {
            steps {
                script {
                    // inline
                    def stdoutAndStatus = sh script: 'set +x ; ls -a 2>&1 && echo "status:$?" || echo "status:$?" ; exit 0', returnStdout: true
                    echo "stdoutAndStatus: >$stdoutAndStatus<".trim()
                    
                    def stderrAndStatus = sh script: 'set +x ; ls notexisting 2>&1 && echo "status:$?" || echo "status:$?" ; exit 0', returnStdout: true
                    echo "stderrAndStatus: >$stderrAndStatus<".trim()
                    
                    // with function
                    echo "runScript: >${runScript('ls -a')}<".trim()
                    echo "runScript: >${runScript('ls notexisting')}<".trim()
                    
                    // failing the sh step
                    echo "runScript: >${runScript('not_existing_command')}<".trim()
                }
            }
        }
    }
}

控制台输出

[Pipeline] stage
[Pipeline] { (more values from sh)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ set +x
[Pipeline] echo
stdoutAndStatus: >.
..
status:0
<
[Pipeline] sh
+ set +x
[Pipeline] echo
stderrAndStatus: >ls: notexisting: No such file or directory
status:2
<
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ set +x
[Pipeline] }
[Pipeline] // script
[Pipeline] echo
runScript: >.
..
status:0
<
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ set +x
[Pipeline] }
[Pipeline] // script
[Pipeline] echo
runScript: >ls: notexisting: No such file or directory
status:2
<
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ set +x
[Pipeline] }
[Pipeline] // script
[Pipeline] echo
runScript: >C:/Users/jenkins/AppData/Local/Jenkins/.jenkins/workspace/SO-36956977 more values from sh@tmp/durable-af2cee22/script.sh: line 1: not_existing_command: command not found
status:127
<
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

谢谢你的解决方案!然而,Shell脚本步骤并没有显示整个CLI命令,只显示了第一部分:“+ set +x”。你知道有没有办法修复它吗? - Boris
1
@Boris 参见Bash的 set:"_使用 + 而非 - 将会关闭该选项_。" - Gerold Broser

1
在普通(Windows Git)Bash中,它的工作方式如下(受上面问题中@Ian W的评论启发):

stdErrAndOutAndStatus.sh

stdErrAndOutAndStatus () {
    $1 2>&1 ; echo "status:$?"
}

stdOutAndStatus=$( stdErrAndOutAndStatus 'ls -a' )
echo -e "$stdOutAndStatus\n"
stdErrAndStatus=$( stdErrAndOutAndStatus 'ls notexisting' )
echo -e "$stdErrAndStatus\n"
stdErrAndStatus=$( stdErrAndOutAndStatus 'not_existing_command' )
echo -e "$stdErrAndStatus\n"

输出

$ ./stdErrAndOutAndStatus.sh
.
..
stdErrAndOutAndStatus.sh
status:0

ls: cannot access 'notexisting': No such file or directory
status:2

./stdErrAndOutAndStatus.sh: line 3: not_existing_command: command not found
status:127

注意:我希望没有我不知道的Bash陷阱。我不经常编写脚本。


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