2016-05-13 208 views
5

我的管道中的一个步骤将.tar上传到artifactory服务器。传入env.BUILD_NUMBER时,我得到一个错误的替换错误,但是当硬编码时,相同的命令有效。脚本通过jenkins用groovy编写,并在jenkins工作区中运行。Jenkins管道sh坏代换

sh 'curl -v --user user:password --data-binary ${buildDir}package${env.BUILD_NUMBER}.tar -X PUT "http://artifactory.mydomain.com/artifactory/release-packages/package${env.BUILD_NUMBER}.tar"' 

返回错误:

[Pipeline] sh 
[Package_Deploy_Pipeline] Running shell script 
/var/lib/jenkins/workspace/[email protected]/durable-4c8b7958/script.sh: 2: 
/var/lib/jenkins/workspace/[email protected]/durable-4c8b7958/script.sh: Bad substitution 
[Pipeline] } //node 
[Pipeline] Allocate node : End 
[Pipeline] End of Pipeline 
ERROR: script returned exit code 2 

如果在一个版本号,换出${env.BUILD_NUMBER}硬代码我没有得到任何错误,代码成功运行。

sh 'curl -v --user user:password --data-binary ${buildDir}package113.tar -X PUT "http://artifactory.mydomain.com/artifactory/release-packages/package113.tar"' 

我用$ {} env.BUILD_NUMBER其他SH命令在同一个脚本中和在任何其他地方没有问题。

+0

我的猜测是'$ {env。BUILD_NUMBER}'被其他实例中的shell实际看到之前正在被预处理步骤替代。 'sh'本身正确地把它当作错误来对待。 – chepner

+0

在这行之前使用$ {env.BUILD_NUMBER}以完全相同的方式上传到Google存储,并且这不会给我带来任何问题。 编辑:我也做了一个虚拟变量,并将其设置为一个数字,然后传递给变量,并得到同样的问题。 –

+2

你可能会在整个事件中使用错误的引号http://mrhaki.blogspot.com.au/2009/08/groovy-goodness-string-strings-strings.html。你也不需要引用curl的URL。因此,可能在整个事件中使用双引号将不会产生任何单引号 – KeepCalmAndCarryOn

回答

18

原来这是一个语法问题。将'中的命令包含在${env.BUILD_NUMBER中,而不是其值。我将整个命令封装在" s中并逃脱嵌套。现在工作正常。

sh "curl -v --user user:password --data-binary ${buildDir}package${env.BUILD_NUMBER}.tar -X PUT \"http://artifactory.mydomain.com/artifactory/release-packages/package${env.BUILD_NUMBER}.tar\"" 
+1

就像我说的? ;) – KeepCalmAndCarryOn

+0

是啊,你钉了它,感谢所有的帮助。尽管如此,我仍然错过了你的原创评论,希望我早点读过它。 –

+0

与此问题没有直接关系,但请考虑使用Artifactpry Pipeline DSL。它比curl cmd执行提供更方便的Groovy DSL,减少了语法错误的机会:https://wiki.jenkins-ci.org/display/JENKINS/Artifactory+-+Working+With+the+Plineline+Jenkins+Plugin –

4

通常为最常见的问题:

坏替代

错误是使用sh而不是bash

特别是在使用时詹金斯,如果你使用执行shell,请确保您的命令开始与shebang,例如#!/bin/bash -xe#!/usr/bin/env bash

5

其实,你好像误解了env变量。在您的sh区块中,您应该直接访问${BUILD_NUMBER}

原因/说明:env代表脚本内部的环境。该环境被直接用于/可用于执行的任何事情,例如, shell脚本。

请注意不要写任何东西到env.*,而是使用withEnv{}块代替。

4

我可以肯定地告诉你,这都是关于sh shell和bash shell的。

node { 
    stage("Preparing"){ 
     sh'''#!/bin/bash -xe 
      colls=(col1 col2 col3) 
      for eachCol in ${colls[@]} 
      do 
       echo $eachCol 
      done 
     ''' 
    }  
} 
0

我是有表示jar文件的artifactory的所述{env.MAJOR_VERSION}问题:我通过指定#!/bin/bash -xe如下固定这个问题。显示我通过在Jenkinsfile中保留环境步骤来接近。

pipeline { 
agent any 
environment { 
MAJOR_VERSION = 1 
} 

stages { 
stage('build') { 
    steps { 
     sh 'ant -f build.xml -v' 
} 
} 
} 
post { 
always{ 
    archiveArtifacts artifacts: 'dist/*.jar', fingerprint: true 
} 
} 
} 

我解决了问题,然后在我的Jenkins构建输出中没有显示出错误的替换。所以环境步骤在Jenkins文件中扮演更重要的角色。