【问题标题】:Getting File not found exception on reading a file in Jenkins pipeline在 Jenkins 管道中读取文件时获取文件未找到异常
【发布时间】:2022-01-07 02:44:05
【问题描述】:

文件位于 Linux 工作节点上的 /opt/apps/workspace/build32/target/site/result.html。构建在/opt/apps/workspace/build32 文件夹下运行。下面是我正在使用的代码 sn-p。

if (fileExists("/opt/apps/workspace/build32/target/site/result.html")) {
  echo "result.html file exist"
}
else {
  echo " File does not exist"
}
def file = new File("/opt/apps/workspace/build32/target/site/result.html").collect{it}
def index = file.findIndexOf{ it ==~ /.*Result.*/ }
echo "file[index]"

输出:

Running in /opt/apps/workspace/build32. 
[pipeline] result.html file exist 
[pipeline] build status UNSTABLE build message there was an error on stage Test, result.html (No such file or directory)

【问题讨论】:

  • 输出:在 /opt/apps/workspace/build32 中运行。 [pipeline] [pipeline] result.html 文件存在 [pipeline] build status UNSTABLE build message there was an error on stage Test, result.html (No such file or directory)

标签: jenkins groovy jenkins-pipeline jenkins-groovy


【解决方案1】:

问题

您需要注意,运行任意 Groovy(或 Java)代码总是在您的 Jenkins 主节点上执行,无论哪个工作节点在您的管道中执行代码。 Jenkins Pipeline 步骤是此规则的一个例外,它们在当前工作节点上执行。这就是为什么:

fileExists("/opt/apps/workspace/build32/target/site/result.html")

打印预期的输出,因为fileExists 是标准的 Jenkins 流水线步骤,因此它在工作节点上执行,该工作节点在其工作区中创建文件。 值得一提的是,流水线步骤可以在声明性流水线的steps { } 块或script { } 块内使用,也可以直接在脚本化流水线代码中使用。

当你打电话时:

def file = new File("/opt/apps/workspace/build32/target/site/result.html").collect{it}

您收到错误是因为new File(...) 在 Jenkins 主节点上执行,并且其工作区不包含在工作节点的工作区中创建的文件。

解决方案

您可以使用readFile pipeline step,而不是执行任意Groovy 代码,该步骤将使用当前工作节点及其工作区读取文件。您可以使用相对路径访问工作空间内的文件,因此应该读取文件内容:

def file = readFile(file: 'target/site/result.html')

请记住,readFile 步骤将文件的内容作为单个 String 返回,因此如果您想逐行处理它,您可能必须执行以下操作:

def lines = readFile(file: 'target/site/result.html').readLines()

以下代码将从文件中生成List<String> 行。根据您的 Jenkins 配置,String.readLines() 方法可能需要加入白名单,然后您才能在 Jenkins 管道代码中使用它。

【讨论】:

  • 感谢@Szymon Stepnaik 的详细解释。我正在尝试使用 readFile 但被击中了。首先我必须读取文件,然后在文件中搜索字符串“Result”,然后从匹配中打印第三行。您能否建议我如何使用 readFile 来做到这一点。
  • 当你使用readFile读取文件的文本时,你可以使用readLines()甚至split('\n')将它变成一个列表。然后您可以在该列表上调用findIndexOf { it =~ /Result/ } 以获取其中包含Result 的行的索引。 readLinessplit 方法可能确实需要白名单 - 如果是这种情况,您将在管道日志中收到错误,其中包含指向管理页面的链接,您可以在其中允许在管道代码中使用该方法.当你重新运行它时,你应该得到结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 2021-11-23
相关资源
最近更新 更多