Gradle에서 현재 OS를 감지하는 방법


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

또한 함께, OS 버전을 얻을 수 있습니다System.getProperty('os.arch')
케빈 Welker

13
"WINDOWS".toLowerCase()로케일에 따라 다르며 wındows로케일이 터키어 인 시스템에서 리턴됩니다 (점없는 i 참고). toLowerCase(Locale.ROOT)대신 사용 하여 안전한 편에 서십시오.
Matthias Braun

답변:


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 / branches / RB-0.3 / build.gradle


8
Os.isFamily (Os.FAMILY_MAC는) 유효한 또한 동안 경고, Os.isFamily (Os.FAMILY_UNIX)은 유닉스와 맥 (모두 true를 돌려줍니다
shabunc가

3
이것이 실제로 OS이고 쉘 gradle이 시작된 것에 대해 아무 말도하지 않습니다 (예 : Mingw, Cygwin 또는 다른 bash 쉘일 수 있음). 따라서이를 사용하여 환경 변수를 읽는 경우에는 예상 한 것과 다를 수 있습니다.
estani

2
@shabunc는 org.gradle.internal.os.OperatingSystem 사용하여 더 나은 솔루션이있다
피터 칸

task checkWin() << {왜 필요합니까? 당신은 그냥 쓸 수 있습니다if (Os.isFamily(Os.FAMILY_WINDOWS)) { println "*** WINDOWS " }
user25

또한 사용하는 것이 좋습니다 org.gradle.internal.os.OperatingSystemif (OperatingSystem.current() == OperatingSystem.WINDOWS)(우리가 자신의 구현을 사용하지 왜 Gradle을 이야기하는 경우)
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
변경 되었습니까? Gradle을 2.5을 사용하면 OperatingSystem이하지 않는 것.current()
로스 드류에게

6
내부 패키지를 염두에 두십시오 :org.gradle.internal.os.OperatingSystem.current()
Brian

@danblack OperatingSystem없이 current()어떻게 인스턴스를 얻 습니까?
TWiStErRob

1
다음 중 하나를 찾았습니다. OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem; @PeterNiederwieser
TWiStErRob

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에서 OS를 감지하는 것을 좋아하지 않으며 OperatingSystem클래스에 더 이상 current()메서드 가 포함되어 있지 않습니다 .

따라서 제 생각에는 OS를 감지하는 가장 깨끗한 방법은 다음과 같습니다.

DefaultNativePlatform 가져 오기 :

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

그런 다음 DefaultNativePlatform작업에 사용 하십시오.

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

이 방법은 Gradle 내부 API를 사용하므로 이상적이지 않습니다.

Gradle 4.10으로 테스트되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.