Jenkins 管道:运行 shell 命令返回“错误替换”,但为什么呢?
问题: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
问题: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()
}
更多推荐
所有评论(0)