我的管道中的一个步骤将.tar上传到artifactory服务器。传入env.BUILD_NUMBER时收到错误的替换错误,但是当数字被硬编码时,相同的命令也会起作用。该脚本通过jenkins以groovy编写,并在jenkins工作区中运行。
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/Package_Deploy_Pipeline@tmp/durable-4c8b7958/script.sh: 2:
/var/lib/jenkins/workspace/Package_Deploy_Pipeline@tmp/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"'
我在同一个脚本中的其他sh命令中使用$ {env.BUILD_NUMBER},并且在任何其他地方都没有问题。
答案 0 :(得分:46)
这结果是一个语法问题。在'
中包装命令导致${env.BUILD_NUMBER
传递而不是其值。我将整个命令包装在"
中,然后转义嵌套。现在工作正常。
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 :(得分:16)
实际上,您似乎误解了env
变量。在sh
区块中,您应该直接访问${BUILD_NUMBER}
。
原因/说明: env
表示脚本中的环境。该环境直接用于/可用于任何执行的环境,例如, shell脚本。
另请注意不要向env.*
写任何内容,而是使用withEnv{}
块。
答案 2 :(得分:13)
通常是最常见的问题:
糟糕的替换
错误是使用sh
而不是bash
。
特别是在使用Jenkins时,如果您正在使用执行shell ,请确保您的 Command 以 shebang 开头,例如#!/bin/bash -xe
或#!/usr/bin/env bash
。
答案 3 :(得分:8)
我可以肯定地告诉你,它全部是关于sh shell和bash shell的。我通过指定#!/bin/bash -xe
解决了这个问题,如下所示:
node {
stage("Preparing"){
sh'''#!/bin/bash -xe
colls=( col1 col2 col3 )
for eachCol in ${colls[@]}
do
echo $eachCol
done
'''
}
}
答案 4 :(得分:1)
我遇到了在jar文件的工件中显示{env.MAJOR_VERSION}
的问题。 show我通过在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构建输出中没有显示我的错误替换。所以环境步骤在Jenkinsfile中扮演着更重要的角色。
答案 5 :(得分:1)
在处理 Amazon S3 应用程序上载的 Jenkins 管道时,我遇到了同样的问题。
我的脚本是这样的:
pipeline {
agent any
parameters {
string(name: 'Bucket', defaultValue: 's3-pipeline-test', description: 'The name of the Amazon S3 Bucket')
string(name: 'Prefix', defaultValue: 'my-website', description: 'Application directory in the Amazon S3 Bucket')
string(name: 'Build', defaultValue: 'public/', description: 'Build directory for the application')
}
stages {
stage('Build') {
steps {
echo 'Running build phase'
sh 'npm install' // Install packages
sh 'npm run build' // Build project
sh 'ls' // List project files
}
}
stage('Deploy') {
steps {
echo 'Running deploy phase'
withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWSCredentials', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sh 'aws s3 ls' // List AWS S3 buckets
sh 'aws s3 sync "${params.Build}" s3://"${params.Bucket}/${params.Prefix}" --delete' // Sync project files with AWS S3 Bucket project path
}
}
}
}
post {
success {
echo 'Deployment to Amazon S3 suceeded'
}
failure {
echo 'Deployment to Amazon S3 failed'
}
}
}
这是我修复的方式:
看到这是变量的插值调用,我不得不在脚本的这一行中替换单引号(''):
sh 'aws s3 sync "${params.Build}" s3://"${params.Bucket}/${params.Prefix}" --delete' // Sync project files with AWS S3 Bucket project path
以双引号(“” ):
sh "aws s3 sync ${params.Build} s3://${params.Bucket}/${params.Prefix} --delete" // Sync project files with AWS S3 Bucket project path
所以我的脚本随后如下所示:
pipeline {
agent any
parameters {
string(name: 'Bucket', defaultValue: 's3-pipeline-test', description: 'The name of the Amazon S3 Bucket')
string(name: 'Prefix', defaultValue: 'my-website', description: 'Application directory in the Amazon S3 Bucket')
string(name: 'Build', defaultValue: 'public/', description: 'Build directory for the application')
}
stages {
stage('Build') {
steps {
echo 'Running build phase'
sh 'npm install' // Install packages
sh 'npm run build' // Build project
sh 'ls' // List project files
}
}
stage('Deploy') {
steps {
echo 'Running deploy phase'
withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWSCredentials', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sh 'aws s3 ls' // List AWS S3 buckets
sh "aws s3 sync ${params.Build} s3://${params.Bucket}/${params.Prefix} --delete" // Sync project files with AWS S3 Bucket project path
}
}
}
}
post {
success {
echo 'Deployment to Amazon S3 suceeded'
}
failure {
echo 'Deployment to Amazon S3 failed'
}
}
}
仅此而已
我希望这会有所帮助
答案 6 :(得分:0)
为了将常规参数传递到Jenkins管道中的bash脚本中(有时会导致错误的替换)您有2个选择:
三重双引号方式[“”“] 要么 三重单引号方式[''']
function myAlerts() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sheet=ss.getSheetByName("Campaign List");
var range=sheet.getDataRange();
var values=range.getDisplayValues();
var lastRow=range.getLastRow();
var curDate=values[1][11];
var anyMatches=false;
var message="";
var sheetUrl=ss.getUrl();
var email=Session.getActiveUser().getEmail();
var optionalEmail=values[2][12];
if (optionalEmail!=""){
email+="," + optionalEmail;
}
for (var i=1;i<lastRow;i++) {
if (values[i][5].toString()==curDate.toString()) {
message+=Utilities.formatString('<strong>%s</strong> will expire on %s <br />\n"',values[i][1],values[i][5]);
anyMatches=true;
}
}
message+='<br />\n<font color="red">This is an auto-generated email to remind you of your campaign expiration.</font><br />\n'
if (anyMatches) {
MailApp.sendEmail({to: email,subject: 'Campaign Expiration Notice!',htmlBody: message});
}
}
正常显示参数(如果它是环境变量${someVariable}
或注入到您的工作${env.someVariable}
中的参数< / li>
示例:
${env.someVariable}
def YOUR_APPLICATION_PATH= "${WORKSPACE}/myApp/"
sh '''#!/bin/bash
cd ${YOUR_APPLICATION_PATH}
npm install
'''
使用它或将使用 "\${someVaraiable}"
示例:
''' + someVaraiable + '''
OR
def YOUR_APPLICATION_PATH= "${WORKSPACE}/myApp/"
sh '''#!/bin/bash
cd ''' + YOUR_APPLICATION_PATH + '''
npm install
'''