2016-05-13 40 views
5

Krok w moim potoku przesyła .tar do sztucznego serwera. Podczas przejścia w env.BUILD_NUMBER pojawia się błąd Bad substitution, ale te same polecenia działają, gdy numer jest zakodowany. Scenariusz jest napisany w groovy przez jenkins i działa w przestrzeni roboczej Jenkins.Jenkins Pipeline sh bad substitution

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"' 

zwraca błędy:

[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 

Jeśli ciężko kod w wielu kompilacji i swap ${env.BUILD_NUMBER} otrzymuję żadnych błędów i kod przebiega pomyślnie.

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

Używam $ {env.BUILD_NUMBER} ramach innych sh poleceń w tym samym skrypcie i nie mają problemów w innych miejscach.

+0

Zgaduję, że '$ {env.BUILD_NUMBER} 'jest zastępowane przez etap przetwarzania wstępnego, zanim zostanie faktycznie wyświetlony przez powłokę w innych przypadkach. 'sh' samo słusznie traktuje to jako błąd. – chepner

+0

w tej samej funkcji, tuż przed tą linią, używając $ {env.BUILD_NUMBER} w taki sam sposób, aby przesłać do Google Storage i to nie daje żadnych problemów. EDYCJA: Zrobiłem również zmienną obojętną i ustawiłem ją na liczbę, a następnie przekazałem w zmiennej i otrzymałem ten sam problem. –

+2

Możliwe, że używasz niewłaściwych cytatów w całej sprawie http://mrhaki.blogspot.com.au/2009/08/groovy-goodness-string-strings-strings.html. Nie musisz też podawać adresu URL do zawijania. Więc może używanie podwójnych cudzysłowów wokół całego dzieła będzie działało bez pojedynczych cudzysłowów. – KeepCalmAndCarryOn

Odpowiedz

18

To okazało się problemem składni. Zawijanie polecenia w ' spowodowało, że zamiast jego wartości, przekazano ${env.BUILD_NUMBER. Zawinęłem całe polecenie w " s i uciekłem z zagnieżdżonego. Działa teraz dobrze.

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

Tak jak powiedziałem? ;) – KeepCalmAndCarryOn

+0

Tak, przybity, dzięki za pomoc. Tęskniłem za twoim oryginalnym komentarzem, ale chciałbym, aby przeczytałem go wcześniej. –

+0

Nie jest bezpośrednio związany z tym problemem, ale rozważ skorzystanie z DSL programu Pipeline. Zapewnia bardziej wygodne Groovy DSL niż curl cmd egzekucje, zmniejszając szansę na błędy składni: https://wiki.jenkins-ci.org/display/JENKINS/Artifactory+-+pracownicy+Z+Pipeline+Jenkins+Plugin –

4

Zazwyczaj najczęstszym problemem dla:

Bad substytucyjnego

błędem jest użycie sh zamiast bash.

Zwłaszcza przy użyciu Jenkinsa, jeśli używasz Wykonanie powłoki, upewnij się, że poleceń starty z shebang, np #!/bin/bash -xe lub #!/usr/bin/env bash.

5

Właściwie wydaje się, że źle zrozumiałeś zmienną env. W swoim bloku sh należy bezpośrednio uzyskać dostęp do ${BUILD_NUMBER}.

Powód/Objaśnienie:env reprezentuje środowisko wewnątrz skryptu. To środowisko jest używane/dostępne bezpośrednio do wszystkiego, co jest wykonywane, np. skrypty powłoki.

Należy również pamiętać, aby nie pisać niczego pod numerem env.*, ale zamiast tego należy użyć bloków withEnv{}.

4

Zdecydowanie mogę powiedzieć, że wszystko zależy od powłoki sh i powłoki bash. Naprawiłem ten problem poprzez określenie #!/bin/bash -xe następująco:

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

miałem problemu ze wskazaniem {env.MAJOR_VERSION} w artifactory pliku jar. pokażę, że podchodzę do kroku 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 
} 
} 
} 

Problem został rozwiązany, a następnie nie wyświetlał mi nieprawidłowej zamiany w wynikach kompilacji Jenkinsa. więc krok środowiska odgrywa większą rolę w Jenkinsfile.

Powiązane problemy