2016-05-04 3 views
1

Im пытается скопировать полученный файл войны из одного каталога сборки в другой с помощью сценария сценария Jenkins (groovy). Я тестировал команду find/exec/cp в самой системе как пользователь jenkins из той же рабочей области, что и сценарий, и работает отлично (прямая копия с консоли).Выполнение команды Groovy через Jenkins: «find: missing argument to -exec»

String buildNumber = env.BUILD_NUMBER 

def sout = new StringBuffer() 
def serr = new StringBuffer() 

//Create package directory in jenkins job folder 
def packageDir = "${env.JENKINS_HOME}/jobs/Package_Deploy_Pipeline/builds/${buildNumber}/package/" 
def command = "mkdir ${packageDir}" 
def proc = command.execute() 
proc.consumeProcessOutput(sout, serr) 
proc.waitForOrKill(3000) 
println "out> $sout err> $serr" 

command = "find ${env.JENKINS_HOME}/jobs/myJob/builds/lastSuccessfulBuild/archive/build/libs/ -name *.war -exec cp {} ${packageDir} \\;" 
println command 
proc = command.execute() 
proc.consumeProcessOutput(sout, serr) 
proc.waitForOrKill(3000) 
println "out> $sout err> $serr" 

Ошибка видны в консоли выводе является:

[Pipeline] echo 
out> err> 
[Pipeline] echo 
find /var/lib/jenkins/jobs/myJob/builds/lastSuccessfulBuild/archive/build/libs/ -name *.war -exec cp {} /var/lib/jenkins/jobs/Package_Deploy_Pipeline/builds/23/package/ \; 
[Pipeline] echo 
out> err> find: missing argument to `-exec' 

Edit: Я также попытался "*.war", '*.war', \; и ';'

+0

Есть ли '.war' файлы в текущем каталоге? Такое, что '* .war' может быть развязано оболочкой? Процитирует ли этот аргумент? (Я бы не ожидал, что проблема будет здесь, но это может быть, и это потенциальная проблема, которую вы должны исправить в любом случае.) (Что расширяет '$ {env.JENKINS_HOME}' в этой команде?) Удаляет ли '; 'снова помогите? –

+0

Единственный .war находится в исходном каталоге cp. Я попробовал одинарную цитату '*.войны "и получил те же результаты. $ {env.JENKINS_HOME} расширяется до/var/lib/jenkins /, и я знаю, что это правильно из Консольного выхода. Я не уверен, что вы имеете в виду, убегая снова, можете ли вы уточнить? –

+0

Это не связано с проблемой вообще, но 'env.JENKINS_HOME' не является допустимой переменной оболочки. Оболочка не может расширять это. Так что же это? И, ускользнув от него снова, я имел в виду, что, возможно, все, что выполняет команда, удаляет обратную косую черту с '\;', и вы должны попытаться получить '\\;' в командной строке в качестве теста. –

ответ

-1

Я не решал, почему команда была неудача, но Я собираюсь предположить, что его преобразование groovys в sh ломается, когда команды цепочки. Мое решение состояло в том, чтобы разбить команду find и copy.

location = "find ${env.JENKINS_HOME}/jobs/myJob/builds/lastSuccessfulBuild/archive/build/libs/ -name *.war".execute().text 
command = "cp $location ${packageDir}myJob.war" 
proc = command.execute() 
proc.consumeProcessOutput(sout, serr) 
proc.waitForOrKill(3000) 
println "out> $sout err> $serr" 
0

Groovy

Проблема ошибки вы испытываете может быть связано с \; и тот факт, что вы спасаясь за bash/sh команды, когда на самом деле вы не используете bash/sh, но работает find исполняемый ,

Такой же подход должен применяться к параметру -name, где цитирование должно быть удалено из шаблона поиска.

Пример:

command = "find src -name *.txt -exec cp {} dst/ ;" 
println "[cmd] ${command}" 
proc = command.execute() 

def sout = new StringBuffer() 
def serr = new StringBuffer() 
proc.consumeProcessOutput(sout, serr) 
proc.waitForOrKill(1000) 
println "[cmd.out] ${sout}" 
println "[cmd.err] ${serr}" 

Дженкинс

Если вы работаете этот код из Дженкинс и трубопроводной работы, вероятно, наиболее удобный способ был бы использовать встроенный sh шаг.

ш: Shell Script

This step allows a Jenkins server or slave running on Linux or a Unix-like machine to execute a shell script. 
Params: 

script: String - the script to execute 

sh "find src -name '*.txt' -exec cp {} dst/ \;" 

Более подробную информацию о трубопроводном DSL можно найти в Pipeline tutorial.

Pure Groovy

И в конце концов, почему бы не заменить find только с Groovy код:

("src" as File).eachFileRecurse{ 
    if (it.name ==~ ".*\\.txt") { 
     ... 
    } 
} 

не то, что более элегантно?

+0

большой ввод спасибо. Знаете ли вы, если встроенный шаг sh позволяет мне проверять serr и sout, я не видел примеров в учебнике, поэтому я выбрал метод groovy. –

+0

Дополнительная информация о том, как получить статус команды и выводить ее с шага 'sh', http://stackoverflow.com/a/36958537/6128602. – luka5z

+0

Спасибо и отметили. Поскольку у меня есть более сложная логика, основанная на sterr и sout, мне нужно придерживаться строгой реализации .execute(). –

0

Дженкинс с декларативной трубопровода работал только соответственно для меня:

sh 'find . -ipath "*src/header.h" -exec rm {} ";"'

Смежные вопросы