Cách phát hiện hệ điều hành hiện tại từ Gradle


98

Tôi đã tìm thấy câu trả lời này về cách thực hiện với Groovy:

Phát hiện nền tảng (Window hoặc Linux) bởi Groovy / Grails :

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

Có cách nào tốt hơn?


đó là những gì tôi sử dụng, không có toLowerCase().contains()phần, vì tôi chỉ cần tên.
Kevin Welker

Bạn cũng có thể nhận được phiên bản hệ điều hành, vớiSystem.getProperty('os.arch')
Kevin Welker

13
"WINDOWS".toLowerCase()phụ thuộc vào ngôn ngữ và sẽ trả về wındows(lưu ý i không có dấu chấm) trên các máy có ngôn ngữ là Thổ Nhĩ Kỳ. Sử dụng toLowerCase(Locale.ROOT)thay thế để được an toàn.
Matthias Braun

Câu trả lời:


125

Trên thực tế, tôi đã xem xét dự án Gradle và điều này trông gọn gàng hơn một chút vì nó sử dụng cấu trúc hiện có của Ant :

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

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

Tôi đã tìm thấy điều này trong nhánh Gradle sau và nó có vẻ hoạt động tốt. gradle / gradle-core / cành / RB-0,3 / build.gradle


7
được cảnh báo, Os.isFamily (Os.FAMILY_UNIX) sẽ trở thành sự thật cho cả unix và mac (trong khi Os.isFamily (Os.FAMILY_MAC) cũng là hợp lệ
shabunc

3
Hãy cẩn thận, đây thực sự là HĐH và không nói gì về shell gradle đã bắt đầu (ví dụ: nó có thể là Mingw, Cygwin hoặc bash shell khác). Vì vậy, hãy cẩn thận nếu bạn sử dụng nó để đọc các biến môi trường, chúng có thể không giống như những gì bạn mong đợi.
estani

2
@shabunc có giải pháp tốt hơn bằng cách sử dụng org.gradle.internal.os.OperatingSystem
Peter Kahn

task checkWin() << {tại sao bạn cần nó? bạn chỉ có thể viếtif (Os.isFamily(Os.FAMILY_WINDOWS)) { println "*** WINDOWS " }
25

cũng nó tốt hơn để sử dụng org.gradle.internal.os.OperatingSystemif (OperatingSystem.current() == OperatingSystem.WINDOWS)(nếu chúng ta nói về Gradle tại sao không sử dụng hiện thực của riêng mình)
user25

67

Cập nhật giữa năm 2020 : Vẫn đang ấp ủ:

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

Bản cập nhật đầu năm 2019 : current()đã bị gỡ bỏ.

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

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

Hãy nhớ rằng nó vẫn đang ấp .

Cập nhật giữa năm 2018 : giống như nó đã được đề cập trong các nhận xét, bây giờ lớp này đã chuyển sang một gói khác, vì vậy bạn nên sử dụngorg.gradle.nativeplatform.platform.OperatingSystem.current()


Tính đến giữa năm 2015, câu trả lời của Peter Kahn vẫn còn nguyên giá trị. Kích hoạt hồ sơ dựa trên môi trường vẫn là một cái gì đó được thực hiện tương đối dễ dàng hơn trong Maven. Nhưng hãy nhớ rằng điều đó org.apache.tools.ant.taskdefs.condition.Os.isFamilykhông độc quyền theo nghĩa là nếu nó trả về true với một tham số cụ thể thì nó không nhất thiết có nghĩa là nó trả về false cho bất kỳ tham số nào khác. Ví dụ:

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))
    }
}

Nó sẽ trả về true cho cả MacOS Os.FAMILY_MACOs.FAMILY_UNIXtrên MacOS. Thông thường, nó không phải là thứ bạn cần trong các kịch bản xây dựng.

Mặc dù có một cách khác để đạt được điều này bằng cách sử dụng API Gradle 2+, đó là:

import org.gradle.internal.os.OperatingSystem;

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

Kiểm tra tài liệu về giao diện org.gradle.nativeplatform.platform.OperatingSystem . Điều đáng nói là giao diện này được đánh dấu bằng chú thích ấp ủ , đó là, "tính năng hiện đang được hoàn thiện và có thể thay đổi bất cứ lúc nào". Không gian tên "nội bộ" trong việc triển khai cũng cho chúng ta một gợi ý rằng chúng ta nên sử dụng vùng này khi biết rằng điều này có thể thay đổi.

Nhưng cá nhân tôi sẽ đi với giải pháp này. Nó chỉ là tốt hơn nên viết một lớp wrapper để không làm rối tung lên trong trường hợp một cái gì đó sẽ thay đổi trong tương lai.


8
Nó có thay đổi không? Sử dụng Gradle 2.5 OperatingSystemdường như không có.current()
Ross Drew

6
nhớ gói nội bộ:org.gradle.internal.os.OperatingSystem.current()
Brian

@danblack làm cách nào để bạn có được một phiên bản OperatingSystemmà không có current()?
TWiStErRob

1
Đã tìm thấy một OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem:; ước gì có một cái công khai @PeterNiederwieser
TWiStErRob 23/02/19

Vì Mac OS, Windows và Linux không phải là hệ điều hành duy nhất, sẽ rất tuyệt nếu z / OS được đưa vào. Mặc dù đang gặp khó khăn, nhưng lựa chọn không giống ai trong số những người khác có thể thành công.
John Czukkermann

18

Người ta có thể phân biệt môi trường xây dựng giữa Linux, Unix, Windows và OS X - trong khi Gradle nativeplatform.platform.OperatingSystem phân biệt môi trường đích (bao gồm 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.
}

Người ta cũng có thể sử dụng một tác vụ Ant ( nguồn ):

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

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

7

Gradle không cung cấp API công khai để phát hiện hệ điều hành. Do đó các os.thuộc tính hệ thống là đặt cược tốt nhất của bạn.


7

Hoặc bạn có thể định nghĩa osName là một chuỗi ...

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;
}

... và sử dụng nó sau này - để bao gồm một thư viện gốc, ví dụ:

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

Nhưng nó sẽ không thay đổi bất cứ điều gì vì OperatingSystem hoạt động chính xác như mã của bạn:

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;
    }
}

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

Biên tập:

Bạn có thể làm tương tự cho kiến ​​trúc:

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

và:

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

Chỉ cần lưu ý rằng getArch () sẽ trả về:

  • "ppc" trên PowerPC
  • "amd64" trên 64b
  • "i386" HOẶC "x86" trên 32b.

getArch () sẽ trả về "x86" trên Solaris hoặc "i386" cho bất kỳ nền tảng nào khác.

Chỉnh sửa 2:

Hoặc nếu bạn muốn tránh bất kỳ lần nhập nào, bạn có thể chỉ cần tự làm điều đó:

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);
}

4

Tôi không thích phát hiện hệ điều hành trong Gradle thông qua các thuộc tính hoặc tác vụ Ant và OperatingSystemlớp không còn chứa current()phương thức nữa.

Vì vậy, theo ý kiến ​​của tôi, cách sạch nhất để phát hiện hệ điều hành sẽ là:

Nhập DefaultNativePlatform:

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

Sau đó, sử dụng DefaultNativePlatformtrong nhiệm vụ của bạn:

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

Lưu ý rằng phương pháp này không lý tưởng vì nó đang sử dụng API nội bộ của Gradle.

Nó đã được thử nghiệm với Gradle 4.10.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.