You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Jenkins Pipeline运行Python脚本取最后令牌,避免重复执行且显示日志

问题

我原本用这段Jenkins Pipeline代码运行Python脚本,还能拿到输出的最后一个令牌:

A = bat(script:'c:\python27\python.exe D:\A.py', returnStdout: true).tokenize().last

这段代码能正常跑,但我想同时看到Python脚本的日志,就改成了下面这样:

A = bat(script:'c:\python27\python.exe D:\A.py', returnStdout: true).tokenize()
B = A.last
println A

结果坑来了——Python脚本被执行了两次!这完全不是我想要的,有没有办法解决?

解决建议

哈哈,这个坑我之前也踩过!问题出在Jenkins Pipeline的惰性求值机制上:bat这类步骤返回的不是普通字符串,而是一个特殊的对象,每次你去访问它的内容(比如调用tokenize()或者直接打印),它就会重新执行一遍对应的命令。你修改后的代码相当于触发了两次bat的执行逻辑,所以脚本跑了两次。

给你几个靠谱的解决办法:

1. 先把输出存到变量,再处理

最稳妥的方式就是先把bat的输出完整存到一个普通变量里,之后再对这个变量做分词、取最后元素等操作,这样bat只会执行一次:

// 先把脚本的完整输出存下来,只执行一次bat
def fullOutput = bat(script:'c:\\python27\\python.exe D:\\A.py', returnStdout: true).trim()
// 再对保存好的输出做处理
def tokenList = fullOutput.tokenize()
def lastToken = tokenList.last()
// 打印分词后的列表和原始输出(这样就能看到日志了)
println "分词结果:${tokenList}"
println "脚本原始输出:${fullOutput}"

另外提醒一下:Groovy里字符串的反斜杠要转义,所以路径里的\要写成\\,不然会被解析成特殊字符,导致路径出错哦。

2. 让日志直接输出到Jenkins控制台

如果你想让Python脚本的日志直接显示在Jenkins的构建日志里(不用手动打印原始输出),可以用stdout参数捕获输出,同时把returnStdout设为false

def fullOutput = bat(
    script:'c:\\python27\\python.exe D:\\A.py',
    returnStdout: false,  // 让日志直接输出到控制台
    stdout: true           // 同时捕获输出内容
).stdout.trim()
// 后续处理和上面一样
def tokenList = fullOutput.tokenize()
def lastToken = tokenList.last()
println "最后一个令牌:${lastToken}"

这种方式下,Python脚本的所有日志会直接出现在Jenkins的构建记录里,你还能拿到输出内容做后续处理,一举两得。

为什么原来的代码只执行一次?

因为原来的代码是链式调用:bat(...).tokenize().last——整个操作只触发了一次对bat返回对象的访问,所以只会执行一次脚本。而修改后,由于你拆分了操作步骤,间接触发了多次对特殊对象的访问,才导致重复执行。

内容的提问来源于stack exchange,提问作者Yu Zou

火山引擎 最新活动