在 Jenkinsfile 中逐行读取文件 - groovy
Read file line by line in Jenkinsfile - groovy
我有一个简单的输入文件,每行有两个单词,并在 Jenkinsfile (groovy) 中进行解析,但看到一个问题,
pipeline {
agent any
stages {
stage('Test-1') {
steps {
echo 'Building..'
script {
for (x in 1..5) {
println x //0,1,2,3,4,5
}
}
}
}
stage('Test-2 ') {
steps {
script {
File file = new File("my_file.txt")
def line, noOfLines = 0;
file.withReader { reader ->
while ((line = reader.readLine()) != null) {
println "${line}"
noOfLines++
}
}
}
}
}
stage('Test-3') {
steps {
script {
def whole_file_data = readFile(file: 'my_file.txt')
whole_file_data.eachLine { String line ->
def (p1, p2) = line.tokenize()
println("line:${line}")
println("p1:${p1} & p2:${p2}")
}
}
}
}
}
}
Test-1 可以很好地进行测试,
Test-2 给我的错误是
Scripts not permitted to use new java.io.File java.lang.String. Administrators can decide whether to approve or reject this signature.
Test-3 阶段仅打印第一行并发出警告,
[Pipeline] readFile
expected to call java.lang.String.eachLine but wound up catching org.jenkinsci.plugins.workflow.cps.CpsClosure2.call; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
line:1111 one
[Pipeline] echo
我的 Jenkins 版本是 Jenkins 2.249.1
是什么导致了问题?
p1:1111 & p2:One
测试 1:
这是一个 shell 脚本迭代器。我不确定它与其他两个阶段的关系如何,但它很好。
测试 2:
这使用管道中的 File
class 来读取文件系统上的文件。这有两个安全问题需要管理员批准挂起的沙箱模式启用,并且也只适用于问题中使用的 Jenkins master。事实上,您遇到了安全问题,出于所有这些原因,应该避免这种用法。
测试 3:
这在Pipeline中使用了readFile
pipeline step方法。这是最佳实践,应该比测试 2 中的用法更受青睐。文件中的 String 内容被迭代,并以正确的用法打印该行。问题在于行:
def (p1, p2) = line.tokenize()
其中元组 (p1, p2)
从 tokenize
分配给数组 return (并隐式重铸)。正如您在错误中看到的那样,此 lambda 迭代器作用域元组导致管道出现 Cps
问题。您可以通过在 script
块的末尾重新分配给 null
来解决此问题:
p1 = null
p2 = null
或者甚至不首先使用临时变量:
println("p1:${line.tokenize()[0]} & p2:${line.tokenize()[1]}")
然而,一种更安全的替代方法可能是遍历标记化的行,并在不使用换行符的情况下打印它以确保预期的格式。
我有一个简单的输入文件,每行有两个单词,并在 Jenkinsfile (groovy) 中进行解析,但看到一个问题,
pipeline {
agent any
stages {
stage('Test-1') {
steps {
echo 'Building..'
script {
for (x in 1..5) {
println x //0,1,2,3,4,5
}
}
}
}
stage('Test-2 ') {
steps {
script {
File file = new File("my_file.txt")
def line, noOfLines = 0;
file.withReader { reader ->
while ((line = reader.readLine()) != null) {
println "${line}"
noOfLines++
}
}
}
}
}
stage('Test-3') {
steps {
script {
def whole_file_data = readFile(file: 'my_file.txt')
whole_file_data.eachLine { String line ->
def (p1, p2) = line.tokenize()
println("line:${line}")
println("p1:${p1} & p2:${p2}")
}
}
}
}
}
}
Test-1 可以很好地进行测试, Test-2 给我的错误是
Scripts not permitted to use new java.io.File java.lang.String. Administrators can decide whether to approve or reject this signature.
Test-3 阶段仅打印第一行并发出警告,
[Pipeline] readFile
expected to call java.lang.String.eachLine but wound up catching org.jenkinsci.plugins.workflow.cps.CpsClosure2.call; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
line:1111 one
[Pipeline] echo
我的 Jenkins 版本是 Jenkins 2.249.1 是什么导致了问题? p1:1111 & p2:One
测试 1:
这是一个 shell 脚本迭代器。我不确定它与其他两个阶段的关系如何,但它很好。
测试 2:
这使用管道中的 File
class 来读取文件系统上的文件。这有两个安全问题需要管理员批准挂起的沙箱模式启用,并且也只适用于问题中使用的 Jenkins master。事实上,您遇到了安全问题,出于所有这些原因,应该避免这种用法。
测试 3:
这在Pipeline中使用了readFile
pipeline step方法。这是最佳实践,应该比测试 2 中的用法更受青睐。文件中的 String 内容被迭代,并以正确的用法打印该行。问题在于行:
def (p1, p2) = line.tokenize()
其中元组 (p1, p2)
从 tokenize
分配给数组 return (并隐式重铸)。正如您在错误中看到的那样,此 lambda 迭代器作用域元组导致管道出现 Cps
问题。您可以通过在 script
块的末尾重新分配给 null
来解决此问题:
p1 = null
p2 = null
或者甚至不首先使用临时变量:
println("p1:${line.tokenize()[0]} & p2:${line.tokenize()[1]}")
然而,一种更安全的替代方法可能是遍历标记化的行,并在不使用换行符的情况下打印它以确保预期的格式。