如何从Gradle中检测当前的操作系统


99

我找到了有关如何使用Groovy的答案:

通过Groovy / Grails检测平台(Window或Linux)

if (System.properties['os.name'].toLowerCase().contains('windows')) {
    println "it's Windows"
} else {
    println "it's not Windows"
}

有没有更好的办法?


这就是我所使用的,没有toLowerCase().contains()一部分,因为我只需要名称。
Kevin Welker 2012年

您还可以通过System.getProperty('os.arch')
Kevin Welker 2012年

13
"WINDOWS".toLowerCase()取决于语言环境,并且wındows在语言环境为土耳其语的计算机上将返回(请注意,无点i)。toLowerCase(Locale.ROOT)为了安全起见,请改用它。
Matthias Braun 2015年

Answers:


128

实际上,我看了Gradle项目,由于它使用了Ant的现有结构,因此看起来更简洁一些:

import org.apache.tools.ant.taskdefs.condition.Os

task checkWin() << {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        println "*** Windows "
    }
}

我在下面的Gradle分支中找到了它,并且看起来工作得很好。gradle / gradle-core / branchs / RB-0.3 / build.gradle


8
请注意,Os.isFamily(Os.FAMILY_UNIX)对于UNIX和Mac都将返回true(而Os.isFamily(Os.FAMILY_MAC)也是有效的
shabunc 2015年

3
请注意,这确实是操作系统,并且没有说起关于外壳gradle的任何信息(例如,可能是Mingw,Cygwin或其他bash shell)。因此,如果使用它来读取环境变量,请务必小心,它们可能不是您期望的。
estani

2
@shabunc使用org.gradle.internal.os.OperatingSystem有更好的解决方案
Peter Kahn

task checkWin() << {你为什么需要它?您可以编写if (Os.isFamily(Os.FAMILY_WINDOWS)) { println "*** WINDOWS " }
user25

也这是更好地使用org.gradle.internal.os.OperatingSystemif (OperatingSystem.current() == OperatingSystem.WINDOWS)(如果我们谈论摇篮为什么不使用自己的实现)
user25

70

2020年中更新:仍在孵化中:

OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem; 

2019早期更新current()已删除

org.gradle.nativeplatform.platform.OperatingSystem.getDisplayName()

org.gradle.nativeplatform.platform.OperatingSystem.isLinux()

请记住,它仍在孵化中

2018年中更新:就像评论中提到的那样,现在该类移至其他软件包,因此应使用org.gradle.nativeplatform.platform.OperatingSystem.current()


截至2015年中,彼得·卡恩(Peter Kahn)的答案仍然有效。在Maven中,基于环境的配置文件激活仍然相对容易一些。但是请记住,这org.apache.tools.ant.taskdefs.condition.Os.isFamily并不是排他性的,如果它对一个特定参数返回true,则不一定意味着对其他任何参数返回false。例如:

import org.apache.tools.ant.taskdefs.condition.Os
task detect {
    doLast {
        println(Os.isFamily(Os.FAMILY_WINDOWS))
        println(Os.isFamily(Os.FAMILY_MAC))
        println(Os.isFamily(Os.FAMILY_UNIX))
    }
}

在MacOS Os.FAMILY_MACOs.FAMILY_UNIXMacOS上,它将返回true 。通常,在构建脚本中不需要它。

还有另一种使用Gradle 2+ API实现此目的的方法,即:

import org.gradle.internal.os.OperatingSystem;

task detect {
    doLast {
        println(OperatingSystem.current().isMacOsX())
        println(OperatingSystem.current().isLinux())
    }
}

请查阅org.gradle.nativeplatform.platform.OperatingSystem接口的文档。值得一提的是,该接口带有孵化标记注释,即“该功能目前仍在开发中,可能随时更改”。实现中的“内部”名称空间也向我们暗示了我们应该使用此提示,因为这会发生变化。

但就我个人而言,我会采用这种解决方案。只是编写一个包装器类更好,以免在将来发生某些变化时避免混乱。


8
它改变了吗?OperatingSystem似乎没有使用Gradle 2.5.current()
Ross Drew

6
请注意内部包装:org.gradle.internal.os.OperatingSystem.current()
Brian

@danblack如何获得OperatingSystem不带实例的实例current()
TWiStErRob '19

1
实测值之一:OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem; 希望有一个公开的@PeterNiederwieser
TWiStErRob '19

由于Mac OS,Windows和Linux不是唯一的操作系统,因此如果包含z / OS,那就太好了。尽管处于紧要关头,但选择不做其他任何选择也是可行的。
John Czukkermann

18

可以在Linux,Unix,Windows和OS X之间区分构建环境,而Gradle nativeplatform.platform.OperatingSystem可以区分目标环境(包括FreeBSDSolaris)。

import org.gradle.internal.os.OperatingSystem

String osName = OperatingSystem.current().getName();
String osVersion = OperatingSystem.current().getVersion();
println "*** $osName $osVersion was detected."

if (OperatingSystem.current().isLinux()) {
    // Consider Linux.
} else if (OperatingSystem.current().isUnix()) {
    // Consider UNIX.
} else if (OperatingSystem.current().isWindows()) {
    // Consider Windows.
} else if (OperatingSystem.current().isMacOsX()) {
    // Consider OS X.
} else {
    // Unknown OS.
}

也可以使用Ant任务(source):

import org.apache.tools.ant.taskdefs.condition.Os

task checkWin() << {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        // Consider Windows.
    }
}

7

Gradle没有提供用于检测操作系统的公共API。因此,os.系统属性是您最好的选择。


7

或者您可以将osName定义为字符串...

import org.gradle.internal.os.OperatingSystem

switch (OperatingSystem.current()) {
    case OperatingSystem.LINUX:
        project.ext.osName = "Linux";
        break;
    case OperatingSystem.MAC_OS:
        project.ext.osName = "macOS";
        break;
    case OperatingSystem.WINDOWS:
        project.ext.osName = "Windows";
        break;
}

...并在以后使用-例如包含本机库:

run {
    systemProperty "java.library.path", "lib/$osName"
}

但这不会改变任何东西,因为OperatingSystem的工作原理与您的代码完全相同:

public static OperatingSystem forName(String os) {
    String osName = os.toLowerCase();
    if (osName.contains("Windows")) {
        return WINDOWS;
    } else if (osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx")) {
        return MAC_OS;
    } else if (osName.contains("sunos") || osName.contains("solaris")) {
        return SOLARIS;
    } else if (osName.contains("linux")) {
        return LINUX;
    } else if (osName.contains("freebsd")) {
        return FREE_BSD;
    } else {
        // Not strictly true
        return UNIX;
    }
}

来源:https : //github.com/gradle/gradle/blob/master/subprojects/base-services/src/main/java/org/gradle/internal/os/OperatingSystem.java

编辑:

您可以对架构执行相同的操作:

project.ext.osArch = OperatingSystem.current().getArch();
if ("x86".equals(project.ext.osArch)) {
    project.ext.osArch = "i386";
}

和:

run {
    systemProperty "java.library.path", "lib/$osName/$osArch"
}

请注意,getArch()将返回:

  • PowerPC上的“ ppc”
  • 在64b上为“ amd64”
  • 32b上为“ i386”或“ x86”。

对于其他平台,getArch()将在Solaris上返回“ x86”,在其他平台上返回“ i386”。

编辑2:

或者,如果您想避免任何导入,则可以自己完成:

def getOsName(project) {
    final String osName = System.getProperty("os.name").toLowerCase();

    if (osName.contains("linux")) {
        return ("linux");
    } else if (osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx")) {
        return ("macos");
    } else if (osName.contains("windows")) {
        return ("windows");
    } else if (osName.contains("sunos") || osName.contains("solaris")) {
        return ("solaris");
    } else if (osName.contains("freebsd")) {
        return ("freebsd");
    }
    return ("unix");
}

def getOsArch(project) {
    final String osArch = System.getProperty("os.arch");

    if ("x86".equals(osArch)) {
        return ("i386");
    }
    else if ("x86_64".equals(osArch)) {
        return ("amd64");
    }
    else if ("powerpc".equals(osArch)) {
        return ("ppc");
    }
    return (osArch);
}

尚未要求该体系结构-重新发明轮子是无用的努力。这可能是个人喜好,但是只要可以使用导入,大多数程序员都会使用导入(使用框架,但不使用框架,只会产生重复的代码)。
Martin Zeitler

4

我不喜欢通过属性或Ant任务在Gradle中检测操作系统,并且OperatingSystem该类不再包含current()方法。

因此,我认为,检测操作系统的最干净方法是:

导入DefaultNativePlatform:

import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform

然后DefaultNativePlatform在您的任务中使用:

if (DefaultNativePlatform.getCurrentOperatingSystem().isWindows()) {
   println 'Windows'
}

请注意,此方法并不理想,因为它正在使用Gradle内部API。

已使用Gradle 4.10进行了测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.