问题:Jenkins 管道:运行 shell 命令返回“错误替换”,但为什么呢?

我想用命令的输出填充 groovy 变量“committer”:

def committer = utils.sh("curl -s -u \${J_USER}:\${J_PASS} \${env.BUILD_URL}/api/json | python -mjson.tool | grep authorEmail | awk '{print \$2}' | tr -d '"|,' ")

由于 Jenkins(JENKINS-26133)中的已知问题,不可能这样做,只能使用命令的退出状态填充变量。

所以我有这两个功能:

def gen_uuid(){
    randomUUID() as String
}

def sh_out(cmd){ // As required by bug JENKINS-26133
    String uuid = gen_uuid()
    sh """( ${cmd} )> ${uuid}"""
    String out = readFile(uuid).trim()
    sh "set +x ; rm ${uuid}"
    return out
}

这些功能允许我在sh_out(COMMAND)中包装我的 shell 命令,并且在后台我使用上面提到的已知问题链接中建议的解决方法,这意味着在将命令的输出重定向到文件时运行命令(在这种情况下我的函数是一个随机文件名),然后将它读入一个变量。

因此,在我的管道开始时,我加载了以return this;结尾的函数文件,如下所示:

fileLoader.withGit('git@bitbucket.org:company/pipeline_utils.git', 'master', git_creds, ''){
    utils = fileLoader.load('functions.groovy');
}

这就是您在命令中看到“utils.sh_out”的原因,但是当我在 Jenkins 管道中使用上面显示的命令时,我收到以下错误:

/home/ubuntu/workspace/-6870-bitbucket-integration-ECOPKSSBUJ6HCDNM4TOY77X7UTZ@tmp/durable-006d5c7e/script.sh: 2: /home/ubuntu/workspace/-6870-bitbucket-integration-ECOPKSSBUJ6HCDNM4TOY77X7UTZ@tmp/durable-006d5c7e/script.sh: Bad substitution

在 shell 中运行命令可以正常工作:

$ curl -s -u user:password http://IPADDR:8080/job/COMPANY_BitBucket_Integration/job/research/job/COMPANY-6870-bitbucket-integration/3/api/json/api/json | python -mjson.tool | grep authorEmail | awk '{print $2}' | tr -d '"|,'
user@email.com

我怀疑它最终与tr命令有关,并且与我在那里所做的角色转义有关,但是无论我尝试什么都失败了,有人知道吗?

解答

根据文档现在sh支持标准输出。

我知道我没有直接回答你的问题,但我建议使用 groovy 来解析 json。

您正在尝试从 json 获取authorEmail的值

如果来自/api/json的响应看起来像这样(只是一个例子):

{
  "a":{
    "b":{
      "c":"ccc",
      "authorEmail":"user@email.com"
    }
  }
}

然后 groovy 取athorEmail:

def cmd = "curl -s -u \${J_USER}:\${J_PASS} \${env.BUILD_URL}/api/json"
def json = sh(returnStdout: true, script: cmd).trim()
//parse json and access it as an object (Map/Array)
json = new groovy.json.JsonSlurper().parseText(json)
def mail = json.a.b.athorEmail

你可以收到java.io.NotSerializableException 在这里解释

所以我改变了这样的代码:

node {
    def json = sh(
            returnStdout: true, 
            script: "curl -s -u \${J_USER}:\${J_PASS} \${env.BUILD_URL}/api/json"
        ).trim()
    def mail = evaluateJson(json, '${json.a.b.authorEmail}')
    echo mail
}

@NonCPS
def evaluateJson(String json, String gpath){
    //parse json
    def ojson = new groovy.json.JsonSlurper().parseText(json)
    //evaluate gpath as a gstring template where $json is a parsed json parameter
    return new groovy.text.GStringTemplateEngine().createTemplate(gpath).make(json:ojson).toString()
}
Logo

CI/CD社区为您提供最前沿的新闻资讯和知识内容

更多推荐