[groovy] Jenkinsfile (groovy)에서 변수로 쉘 명령의 출력을 얻는 방법은 무엇입니까?

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.


답변

현재 파이프 라인 버전을 기본적으로 지원 returnStdout하고 returnStatus가능에서 출력 또는 상태를 얻을 수 있도록, sh/ bat단계.

예를 들면 :

def ret = sh(script: 'uname', returnStdout: true)
println ret

공식 문서 .


답변

빠른 답변은 다음과 같습니다.

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]} "

    }
}


답변

groovy가 아닌 후속 쉘 명령에서 출력을 사용해야하는 사람들을 위해 다음 예제와 같이 수행 할 수 있습니다.

    stage('Show Files') {
        environment {
          MY_FILES = sh(script: 'cd mydir && ls -l', returnStdout: true)
        }
        steps {
          sh '''
            echo "$MY_FILES"
          '''
        }
    }

코드 maven 의 예제 가 매우 유용하다는 것을 알았습니다 .


답변

가장 쉬운 방법은이 방법으로 사용하는 것입니다

my_var=`echo 2`
echo $my_var

출력 : 2

작은 따옴표가 아니라는 것은 백 따옴표 (`)입니다.