首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Jenkins管道中通过迭代将shell输出重定向到变量

如何在Jenkins管道中通过迭代将shell输出重定向到变量
EN

Stack Overflow用户
提问于 2021-09-10 10:13:21
回答 1查看 88关注 0票数 0

我希望迭代名为envContentKeys = ["Address", "Name", "Date"]的数组中的每个元素,通过重定向json文件config.json中的值为数组中的每个元素创建新的环境变量。

这是config.json

代码语言:javascript
复制
{
   "dev":{
          "Name": "Apple",
          "Address": "somewhere",
          "Date": "10Sep2021"
         },

   "prod":{
          "Name": "Orange",
          "Address": "somewhere2",
          "Date": "15Sep2021"
         }
}

我在管道中所做的是调用.each并将envContentKeys中的元素指定为环境

代码语言:javascript
复制
 envContentKeys.each {
     env."${it}" = sh(
                      script: "jq -r '.${params.environment}.${it}' config.json",
                      returnStdout: true
                   ).trim()
 }

${params.environment}将取决于用户的选择是dev还是prod

最终结果应该如下所示

用于开发env.Address = somewhere env.Name = Apple env.Date = 10Sep2021

但是,管道会给出错误

代码语言:javascript
复制
an exception which occurred:
    in field com.cloudbees.groovy.cps.impl.FunctionCallEnv.locals
    in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@63b12f64
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@6c55c234
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.LoopBlockScopeEnv@498d2924
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@748e1123
    in field com.cloudbees.groovy.cps.impl.CallEnv.caller
    in object com.cloudbees.groovy.cps.impl.ClosureCallEnv@16dc3a96
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@29d584b3
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@691424c3
    in field com.cloudbees.groovy.cps.impl.CallEnv.caller
    in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@1769e279
    in field com.cloudbees.groovy.cps.Continuable.e
    in object org.jenkinsci.plugins.workflow.cps.SandboxContinuable@2ec694c5
    in field org.jenkinsci.plugins.workflow.cps.CpsThread.program
    in object org.jenkinsci.plugins.workflow.cps.CpsThread@767fe543
    in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.threads
    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@2bd4e7db
    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@2bd4e7db
Caused: java.io.NotSerializableException: java.util.ArrayList$Itr
EN

回答 1

Stack Overflow用户

发布于 2021-09-10 11:39:33

这样的东西在不使用shell的情况下也能正常工作。

代码语言:javascript
复制
params.environment = 'prod'
...

def cfg = readJSON file:"config.json"
env.putAll( cfg[ params.environment ] )

如果您仍然想使用shell来计算json-path...

jenkins管道尝试序列化并存储步骤之间的所有变量,因为下一步可能在不同的节点上运行。

java.io.NotSerializableException这样的错误意味着你有这样一个不可序列化的变量。

java.io.NotSerializableException: java.util.ArrayList$Itr应该会给你一个提示,它发生在数组周围的某个地方。和Itr --这是关于迭代器的(猜测)。

实际上array.each {}使用的是迭代器..

修复它的2个主要选项

1.尝试将不可序列化对象更改为可序列化对象

java.util.ArrayList$Itr不可序列化,但ArrayList本身是可序列化的-请在相应的javadoc中查找All Implemented Interfaces: Serializable

因此,数组本身很好,您可以尝试更改将数组迭代为标准for的方式

代码语言:javascript
复制
for (int i=0; i<envContentKeys.size(); i++){
    def it = envContentKeys[i]
    env[it] = sh(...)
}

现在不能检查这个,但我认为它应该可以工作,因为循环中使用的所有变量都是可序列化的。

2.在导致问题的代码周围使用@NonCPS注释

将您的代码移到function中,并向此函数添加@NonCPS注释。这将强制管道将其作为一个不可破坏的步骤来执行。

代码语言:javascript
复制
@NonCPS
def myFunction() {
    envContentKeys.each {
        env[it] = sh(...)
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69130686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档