首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jenkins管道:运行shell命令会返回“坏替换”,但是为什么呢?

Jenkins管道:运行shell命令会返回“坏替换”,但是为什么呢?
EN

Stack Overflow用户
提问于 2017-06-14 10:55:57
回答 1查看 4K关注 0票数 1

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

代码语言:javascript
复制
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 (詹金斯-26133)中已知的问题,所以不可能这样做,而只能使用命令的退出状态填充变量。

我做了这两个函数:

代码语言:javascript
复制
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
}

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

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

代码语言:javascript
复制
fileLoader.withGit('git@bitbucket.org:company/pipeline_utils.git', 'master', git_creds, ''){
    utils = fileLoader.load('functions.groovy');
}

这就是为什么您在命令中看到的"utils.sh_out“,但是当我在Jenkins管道中使用上面所示的命令时,我会得到以下错误:

代码语言:javascript
复制
/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中运行命令可以正常工作:

代码语言:javascript
复制
$ 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命令有关,与我在那里所做的角色转义有关,但无论我尝试什么失败,都有人有主意吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-14 13:05:29

根据现在的文档sh支持std输出。

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

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

如果来自/api/json的响应如下(仅举一个例子):

代码语言:javascript
复制
{
  "a":{
    "b":{
      "c":"ccc",
      "authorEmail":"user@email.com"
    }
  }
}

然后用groovy来获取athorEmail

代码语言:javascript
复制
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在这里解释了

所以我就这样修改了代码:

代码语言:javascript
复制
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()
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44542800

复制
相关文章

相似问题

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