Come rilevare il sistema operativo corrente da Gradle


98

Ho trovato questa risposta su come farlo con Groovy:

Rilevamento della piattaforma (Windows o Linux) da Groovy / Grails :

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

C'è un modo migliore?


è quello che uso, senza la toLowerCase().contains()parte, perché mi serve solo il nome.
Kevin Welker,

Puoi anche ottenere la versione del sistema operativo, conSystem.getProperty('os.arch')
Kevin Welker,

13
"WINDOWS".toLowerCase()dipende dalla locale e restituirà wındows(notare la i senza punto) su macchine in cui la lingua è turca. Usa toLowerCase(Locale.ROOT)invece per essere al sicuro.
Matthias Braun

Risposte:


125

In realtà, ho esaminato il progetto Gradle, e questo sembra un po 'più pulito poiché utilizza la struttura esistente di Ant :

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

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

L'ho trovato nel seguente ramo di Gradle e sembra funzionare bene. gradle / gradle-core / branch / RB-0.3 / build.gradle


7
attenzione, Os.isFamily (Os.FAMILY_UNIX) restituirà true sia per unix che per mac (mentre anche Os.isFamily (Os.FAMILY_MAC) è valido
shabunc

3
Fai attenzione che questo sia effettivamente il sistema operativo e non dice nulla sulla shell gradle avviata (ad esempio potrebbe essere Mingw, Cygwin o un'altra shell bash). Quindi fai attenzione se lo usi per leggere le variabili d'ambiente, potrebbero non essere quelle che ti aspetti.
estani

2
@shabunc ha una soluzione migliore utilizzando org.gradle.internal.os.OperatingSystem
Peter Kahn

task checkWin() << {perchè ne hai bisogno? puoi semplicemente scrivereif (Os.isFamily(Os.FAMILY_WINDOWS)) { println "*** WINDOWS " }
user25

inoltre è meglio usare org.gradle.internal.os.OperatingSysteme if (OperatingSystem.current() == OperatingSystem.WINDOWS)(se parliamo di Gradle perché non usare le proprie implementazioni)
user25

67

Aggiornamento di metà 2020 : ancora in incubazione:

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

Aggiornamento all'inizio del 2019 : current()rimosso.

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

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

Tieni presente che è ancora in incubazione .

Aggiornamento di metà 2018 : proprio come è stato menzionato nei commenti, ora questa classe è stata spostata in un pacchetto diverso, quindi dovresti usareorg.gradle.nativeplatform.platform.OperatingSystem.current()


A metà 2015, la risposta di Peter Kahn è ancora valida. L'attivazione del profilo basata sull'ambiente è ancora qualcosa di relativamente più facile in Maven. Ma tieni presente che org.apache.tools.ant.taskdefs.condition.Os.isFamilynon è esclusivo nel senso che se restituisce vero con un particolare parametro non significa necessariamente che restituisce falso per qualsiasi altro parametro. Per esempio:

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

Restituirà vero sia per Os.FAMILY_MACche Os.FAMILY_UNIXsu MacOS. Di solito non è qualcosa di cui hai bisogno negli script di compilazione.

C'è però un altro modo per ottenere questo risultato utilizzando l'API Gradle 2+, ovvero:

import org.gradle.internal.os.OperatingSystem;

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

Consulta la documentazione per l' interfaccia org.gradle.nativeplatform.platform.OperatingSystem . Vale la pena ricordare che questa interfaccia è contrassegnata da un'annotazione di incubazione , ovvero "la funzionalità è attualmente in fase di elaborazione e può cambiare in qualsiasi momento". Lo spazio dei nomi "interno" nell'implementazione ci dà anche un suggerimento che dovremmo usarlo sapendo che questo può cambiare.

Ma personalmente sceglierei questa soluzione. È solo che è meglio scrivere una classe wrapper in modo da non fare confusione nel caso in cui qualcosa cambierà in futuro.


8
È cambiato? L'uso di Gradle 2.5 OperatingSystemnon sembra avere.current()
Ross Drew

6
attenzione al pacchetto interno:org.gradle.internal.os.OperatingSystem.current()
Brian

@danblack come si ottiene un'istanza di OperatingSystemwithout current()?
TWiStErRob

1
Trovato uno: OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem; vorrei che ce ne fosse uno pubblico @PeterNiederwieser
TWiStErRob

Poiché Mac OS, Windows e Linux non sono gli unici sistemi operativi, sarebbe bello se fosse incluso z / OS. Anche se in un pizzico, fare la scelta come non essere nessuno degli altri potrebbe funzionare.
John Czukkermann

18

Si può differenziare l' ambiente di compilazione tra Linux, Unix, Windows e OS X - mentre Gradle nativeplatform.platform.OperatingSystem differenzia l' ambiente di destinazione (inclusi FreeBSD e Solaris ).

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

Si può anche usare un'attività Ant ( fonte ):

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

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

7

Gradle non fornisce un'API pubblica per il rilevamento del sistema operativo. Quindi le os.proprietà del sistema sono la soluzione migliore.


7

Oppure puoi definire osName come una stringa ...

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

... e usalo in seguito, ad esempio per includere una libreria nativa:

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

Ma non cambierebbe nulla poiché OperatingSystem funziona esattamente come il tuo codice:

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

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

Modificare:

Puoi fare lo stesso per l'architettura:

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

e:

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

Tieni presente che getArch () restituirà:

  • "ppc" su PowerPC
  • "amd64" su 64b
  • "i386" O "x86" su 32b.

getArch () restituirà "x86" su Solaris o "i386" per qualsiasi altra piattaforma.

Modifica 2:

Oppure, se vuoi evitare qualsiasi importazione, puoi semplicemente farlo da solo:

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

Non mi piace rilevare il sistema operativo in Gradle tramite proprietà o un'attività Ant e la OperatingSystemclasse non contiene più il current()metodo.

Quindi, a mio parere, il modo più pulito per rilevare il sistema operativo sarebbe:

Importa DefaultNativePlatform:

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

Quindi usa DefaultNativePlatformnel tuo compito:

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

Tieni presente che questo metodo non è l'ideale in quanto utilizza l'API interna di Gradle.

È stato testato con Gradle 4.10.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.