You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Jenkinsfile(Groovy)中获取指定文件夹文件名列表遇问题

解决Jenkins脚本式Pipeline中文件遍历仅返回第一个文件的问题

我看到你在Jenkins脚本式Pipeline里用Groovy的File.traverse方法时遇到了两个核心问题:一是路径解析错误,二是遍历只返回第一个文件。这其实是Jenkins Groovy沙箱限制和原生File类适配问题导致的,下面给你具体的解决方案:

为什么会出现这些问题?

  • 路径解析错误:原生Groovy的new File()是基于Jenkins Master的工作目录来解析路径的,而不是当前Job的工作空间。即使你用env.WORKSPACE拼接路径,也可能因为节点环境差异(比如Agent节点上运行时)出现问题。
  • 遍历仅返回第一个文件:Jenkins的Groovy沙箱会限制某些方法的完整执行,traverse的闭包可能被截断,导致只执行了一次迭代就终止了,这是沙箱安全机制的副作用。

推荐解决方案:使用Jenkins内置的findFiles步骤

Jenkins提供了专门用于文件查找的findFiles步骤,它完全兼容沙箱,能正确识别当前Job的工作空间,而且用法更简单。

修正后的完整Pipeline示例

#!groovy
node('master') {
    FILES_DIR = './foo'
    cleanWs()
    sh """
        mkdir foo
        touch foo/bar1
        touch foo/bar2
        touch foo/bar3
    """
    // 使用findFiles匹配目标目录下的所有文件,再提取文件名
    def fileObjects = findFiles(glob: "${FILES_DIR}/*")
    def filenames = fileObjects.collect { it.name }
    
    // 遍历输出所有文件名
    filenames.each { filename ->
        echo "${filename}"
    }
}

这个脚本会正确输出bar1、bar2、bar3三个文件名。

进阶用法:递归遍历子目录

如果你需要递归遍历所有子目录下的文件,可以调整glob模式,并过滤掉目录:

// 匹配所有子目录下的文件,排除目录本身
def allFiles = findFiles(glob: "${FILES_DIR}/**/*").findAll { !it.directory }
def allFilenames = allFiles.collect { it.name }

替代方案:用Shell命令获取文件列表

如果你更习惯用Shell命令,也可以通过sh步骤执行ls命令并捕获输出:

def filenames = sh(
    script: "ls -1 ${FILES_DIR}",
    returnStdout: true
).trim().split('\n')

这种方式也能可靠获取所有文件名,适合熟悉Shell的场景。

总结

尽量避免在Jenkins Pipeline中使用原生Groovy的File类进行文件操作,优先选择Jenkins官方提供的步骤(如findFiles)或Shell命令,它们更适配Pipeline的运行环境,也不会触发沙箱的限制问题。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:58:41