Jenkins执行Python脚本时return值无法捕获,如何正确获取返回值?
Python脚本return值无法被Jenkins Groovy捕获的疑问
场景复现
我有如下Python脚本myscript.py:
#!/usr/bin/python def main(): return "hello" if __name__ == '__main__': main()
通过Jenkins Groovy执行该脚本:
returnValue = sh(returnStdout: true, script: "python3.9 -u scripts/myscript.py") log.info("returnValue: ${returnValue}")
我预期日志显示returnValue: hello,但实际显示returnValue: 。我理解returnStdout: true会返回Python脚本的标准输出,由于原脚本无标准输出,所以returnValue为空。
为验证这一点,我修改Python脚本,用print替代return输出"hello":
#!/usr/bin/python def main(): print("hello") if __name__ == '__main__': main()
此时Jenkins日志中能正常得到returnValue: hello。
虽然print的方案可行,但我觉得这种方式不够合理且易混淆,因此有两个疑问:
- 该行为是否正确?
- 有没有办法在Python脚本中使用
return关键字,同时让Jenkins Groovy变量捕获到返回值?
问题解答
1. 该行为完全正确
Jenkins的sh(returnStdout: true)捕获的是子进程的标准输出(stdout),而Python函数的return只是将值返回给Python解释器,不会自动输出到标准输出。原脚本中调用main()后,返回值没有被任何代码处理,直接被Python解释器丢弃,整个Python进程的标准输出为空,所以Groovy捕获不到内容。
2. 保留return同时让Groovy捕获返回值的方法
如果想保留return的函数语义,只需把函数的返回值主动输出到标准输出即可,有两种常用方式:
- 方式一:调用函数时打印返回值
修改Python脚本,在主逻辑中打印main()的返回值:
#!/usr/bin/python def main(): return "hello" if __name__ == '__main__': print(main())
这样既保留了main函数用return返回结果的写法,又把结果输出到标准输出,Groovy就能正常捕获。
- 方式二:直接写入标准输出
如果需要精确控制输出内容(比如避免print自动添加的换行符),可以用sys.stdout.write:
#!/usr/bin/python import sys def main(): return "hello" if __name__ == '__main__': sys.stdout.write(main())
另外需要注意:Python脚本的退出码可以通过sh(returnStatus: true)捕获,但退出码只能是整数,无法传递字符串内容,所以传递字符串必须通过标准输出。
内容的提问来源于stack exchange,提问作者anechkayf
相关产品推荐
相关产品推荐

