Jenkinsfile (Groovy)에 이와 같은 것이 있으며 나중에 정보를 사용하기 위해 stdout 및 종료 코드를 변수에 기록하려고합니다.
sh "ls -l"
특히 내부에서 어떤 종류의 그루비 코드도 실행할 수없는 것처럼 보이기 때문에 Jenkinsfile
어떻게 해야 합니까?
Jenkinsfile (Groovy)에 이와 같은 것이 있으며 나중에 정보를 사용하기 위해 stdout 및 종료 코드를 변수에 기록하려고합니다.
sh "ls -l"
특히 내부에서 어떤 종류의 그루비 코드도 실행할 수없는 것처럼 보이기 때문에 Jenkinsfile
어떻게 해야 합니까?
답변:
파이프 라인 sh
단계 의 최신 버전을 사용하면 다음을 수행 할 수 있습니다.
// Git committer email
GIT_COMMIT_EMAIL = sh (
script: 'git --no-pager show -s --format=\'%ae\'',
returnStdout: true
).trim()
echo "Git committer email: ${GIT_COMMIT_EMAIL}"
다른 기능은 returnStatus
옵션입니다.
// Test commit message for flags
BUILD_FULL = sh (
script: "git log -1 --pretty=%B | grep '\\[jenkins-full]'",
returnStatus: true
) == 0
echo "Build full flag: ${BUILD_FULL}"
이 문제를 기반으로 추가 된 옵션 입니다.
명령에 대한 공식 문서 를 참조하십시오 sh
.
WorkflowScript: 97: Expected a step @ line 97, column 17.
script
단계 블록 내에서만 작동하는 것으로 보입니다 . jenkins.io/doc/book/pipeline/syntax/#declarative-steps
현재 파이프 라인 버전을 기본적으로 지원 returnStdout
하고 returnStatus
가능에서 출력 또는 상태를 얻을 수 있도록, sh
/ bat
단계.
예를 들면 :
def ret = sh(script: 'uname', returnStdout: true)
println ret
공식 문서 .
script { }
단계 씩 포장되어야합니다 .
빠른 답변은 다음과 같습니다.
sh "ls -l > commandResult"
result = readFile('commandResult').trim()
sh 단계의 결과를 얻을 수있는 기능 요청이 있다고 생각하지만, 아는 한 현재 다른 옵션은 없습니다.
편집 : JENKINS-26133
EDIT2 : 어떤 버전인지 확실하지 않지만 sh / bat 단계는 표준 출력을 반환 할 수 있습니다.
def output = sh returnStdout: true, script: 'ls -l'
stdout을 얻고 명령이 성공했는지 여부를 알고 싶다면 returnStdout
예외 핸들러에서 사용 하고 랩하십시오.
스크립트 파이프 라인
try {
// Fails with non-zero exit if dir1 does not exist
def dir1 = sh(script:'ls -la dir1', returnStdout:true).trim()
} catch (Exception ex) {
println("Unable to read dir1: ${ex}")
}
출력 :
[Pipeline] sh
[Test-Pipeline] Running shell script
+ ls -la dir1
ls: cannot access dir1: No such file or directory
[Pipeline] echo
unable to read dir1: hudson.AbortException: script returned exit code 2
불행하게도 hudson.AbortException에는 종료 상태를 얻는 데 유용한 방법이 없으므로 실제 값이 필요한 경우 메시지에서 파싱해야합니다 (ugh!)
Javadoc https://javadoc.jenkins-ci.org/hudson/AbortException.html 과 달리이 예외가 발생 해도 빌드가 실패 하지 않습니다 . 잡히지 않으면 실패합니다 !
업데이트 : 쉘 명령에서 STDERR 출력을 원할 경우 Jenkins는 불행히도 일반적인 사용 사례를 올바르게 지원하지 못합니다. 2017 티켓 JENKINS-44930 은 해결책으로 진전을 이루지 않는 동안 평온한 탁구 상태에 빠졌 습니다.
해결책에 관해서는 지금 , 가능한 방법 몇이있을 수 있습니다 :
a) STDERR을 STDOUT으로 리디렉션하십시오 2>&1
-그러나 메인 출력에서 구문 분석하는 것은 당신에게 달려 있습니다. 명령이 실패하면 출력을 얻지 못할 것입니다-예외 처리기에 있기 때문입니다.
b) STDERR을 임시 파일 (이전에 준비한 이름)로 리디렉션합니다 2>filename
(그러나 나중에 파일을 정리해야 함). 주요 코드는 다음과 같습니다.
def stderrfile = 'stderr.out'
try {
def dir1 = sh(script:"ls -la dir1 2>${stderrfile}", returnStdout:true).trim()
} catch (Exception ex) {
def errmsg = readFile(stderrfile)
println("Unable to read dir1: ${ex} - ${errmsg}")
}
c) 다른 방법으로 가서 returnStatus=true
대신 예외 처리기를 사용하지 말고 항상 출력을 파일로 캡처하십시오.
def outfile = 'stdout.out'
def status = sh(script:"ls -la dir1 >${outfile} 2>&1", returnStatus:true)
def output = readFile(outfile).trim()
if (status == 0) {
// output is directory listing from stdout
} else {
// output is error message from stderr
}
주의 사항 : 위 코드는 유닉스 / 리눅스 전용입니다-윈도우는 완전히 다른 쉘 명령을 필요로합니다.
이것은 샘플 케이스입니다.
node('master'){
stage('stage1'){
def commit = sh (returnStdout: true, script: '''echo hi
echo bye | grep -o "e"
date
echo lol''').split()
echo "${commit[-1]} "
}
}
가장 쉬운 방법은이 방법으로 사용하는 것입니다
my_var=`echo 2`
echo $my_var
출력 : 2
작은 따옴표가 아니라는 것은 백 따옴표 (`)입니다.
sh
, 특히 bash 스크립팅에 익숙하지 않은 경우 사람들이 그루비라고 생각할 수 있음을 보여줄 것을 제안합니다 . 방금 Jenkins에서 ls -l
대신 사용해 보았지만 echo 2
작동합니다. 나는 실제로이 접근법을 사용했지만 실제로는 신뢰할 수 없기 때문에 대안을 찾고있었습니다. 이런 식으로 표준 쉘에서 캡처 된보다 복잡한 명령의 출력이 있지만 Jenkins로 이식 될 때 sh
변수는 알 수없는 이유로 아무것도 보유하지 않습니다.