如何确定Jenkins管道中的当前操作系统

时间:2017-05-22 06:16:12

标签: grails jenkins jenkins-pipeline

确定Jenkins管道正在运行的当前操作系统的方法是什么?

背景信息:我正在构建一个应该在所有平台(Windows,OSX,linux)上运行的共享Jenkins管道脚本,并在每个平台上执行不同的操作。

我尝试过类似的事情:

import org.apache.commons.lang.SystemUtils

if (SystemUtils.IS_OS_WINDOWS){
   bat("Command")
}
if (SystemUtils.IS_OS_MAC){
   sh("Command")
}
if (SystemUtils.IS_OS_LINUX){
   sh("Command")
}

但即使它在Windows或Mac node上运行,它也总是进入SystemUtils.IS_OS_LINUX分支

我试过像这样的快速管道。

node('windows ') {
     println ('## OS ' + System.properties['os.name'])
}
node('osx ') {
     println ('## OS ' + System.properties['os.name'])
}
node('linux') {
     println ('## OS ' + System.properties['os.name'])
}

每个节点都在具有正确操作系统的计算机中正确运行,但所有节点都打印## OS Linux

任何想法?

由于 FEDE

5 个答案:

答案 0 :(得分:10)

假设您将Windows作为唯一的非Unix平台,则可以使用管道函数isUnix()uname来检查您所使用的Unix OS:

def checkOs(){
    if (isUnix()) {
        def uname = sh script: 'uname', returnStdout: true
        if (uname.startsWith("Darwin")) {
            return "Macos"
        }
        // Optionally add 'else if' for other Unix OS  
        else {
            return "Linux"
        }
    }
    else {
        return "Windows"
    }
}

答案 1 :(得分:9)

据我所知,Jenkins只区分windows和unix,即如果在windows上,使用bat,在unix / mac / linux上使用sh。因此,您可以使用isUnix()more info here来确定您是在unix还是windows上,并且在unix的情况下使用sh和@Spencer Malone的答案来提供有关该系统的更多信息(如果需要) )。

答案 2 :(得分:2)

我最初使用@fedterzi答案,但发现它有问题,因为它导致了以下崩溃:

org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.Launcher is missing

尝试在管道外部调用isUnix()时(例如,分配变量)。我通过依靠传统的Java方法来确定Os来解决:

def getOs(){
    String osname = System.getProperty('os.name');
    if (osname.startsWith('Windows'))
        return 'windows';
    else if (osname.startsWith('Mac'))
        return 'macosx';
    else if (osname.contains('nux'))
        return 'linux';
    else
        throw new Exception("Unsupported os: ${osname}");
}

这允许在任何管道上下文中调用该函数。

答案 3 :(得分:0)

使用Java类可能不是最好的方法。我很确定除非它是一个jenkins / groovy插件,否则那些在主Jenkins JVM线程上运行。我会研究一种shell方法,例如这里概述的方法:https://stackoverflow.com/a/8597411/5505255

您可以将该脚本包装在shell步骤中以获取stdout,如下所示:

def osName = sh(script: './detectOS', returnStdout: true)

调用上面概述的脚本副本。然后让该脚本返回您想要的操作系统名称,并根据osName var。

返回分支逻辑

答案 4 :(得分:0)

我找到的解决方法是

try{
   sh(script: myScript, returnStdout: true)
 }catch(Exception ex) {
    //assume we are on windows
   bat(script: myScript, returnStdout: true)
 }

或者使用try/catch而不使用env.NODE_LABELS的更优雅的解决方案是使用def isOnWindows(){ def os = "windows" def List nodeLabels = NODE_LABELS.split() for (i = 0; i <nodeLabels.size(); i++) { if (nodeLabels[i]==os){ return true } } return false } 。假设你已经正确标记了所有节点,你可以写一个像这样的函数

if (isOnWindows()) {
    def osName = bat(script: command, returnStdout: true)   
} else {
    def osName = sh(script: command, returnStdout: true)
}

然后

{{1}}