So erkennen Sie Betriebssysteme / Plattformen in Go zuverlässig


75

Folgendes verwende ich derzeit, was meiner Meinung nach die Arbeit erledigt, aber es muss einen besseren Weg geben:

func isWindows() bool {
    return os.PathSeparator == '\\' && os.PathListSeparator == ';'
}

Wie Sie sehen können, muss ich in meinem Fall nur wissen, wie man Fenster erkennt, aber ich möchte wissen, wie man Plattformen / Betriebssysteme erkennt.

Abspielen:

http://play.golang.org/p/r4lYWDJDxL


2
Aktuelle Windows-Versionen funktionieren einwandfrei mit dem Posix-Trennzeichen '/'. Sie benötigen nur einen Backslash für Bat-Skripte und alte Nicht-Posix-Versionen von Windows.
Rick-777

Können Sie "aktuell" definieren? Ich bin erst in den letzten Wochen
hartcodiert worden

2
Windows 95, 98 ME und alle früheren Versionen erfordern einen Backslash. Windows 2000, NT und höher akzeptieren Backslash und Forward Slash als Äquivalente. Backslash bietet Kompatibilität mit älteren Versionen, während Forward Slash die Posix-Konformität gewährleistet.
Rick-777

Vielen Dank für die Klarstellung @ Rick-777.
Mdwhatcott

Antworten:


141

Erkennung zur Kompilierungszeit

Wenn Sie dies tun, um je nach Betriebssystem unterschiedliche Implementierungen zu haben, ist es sinnvoller, separate Dateien mit der Implementierung dieser Funktion zu haben und jeder der Dateien Build-Tags hinzuzufügen. Dies wird an vielen Stellen in der Standardbibliothek verwendet, beispielsweise im osPaket .

Diese sogenannten "Build-Einschränkungen" oder "Build-Tags" werden hier erläutert .

Angenommen, Sie haben die Konstante PATH_SEPARATORund möchten, dass diese Plattform abhängig ist. Sie würden zwei Dateien erstellen, eine für Windows und eine für den (Unix-) Rest:

/project/path_windows.go
/project/path_unix.go

Der Code dieser Dateien wäre dann:

path_windows.go

// +build windows

package project

const PATH_SEPARATOR = '\\'

path_unix.go

// +build !windows

package project

const PATH_SEPARATOR = '/'

Sie können jetzt auf PATH_SEPARATORIhren Code zugreifen und ihn plattformabhängig machen.

Erkennung zur Laufzeit

Wenn Sie das Betriebssystem zur Laufzeit ermitteln möchten, verwenden Sie die runtime.GOOS Variable:

if runtime.GOOS == "windows" {
    fmt.Println("Hello from Windows")
}

Während dies in die Laufzeit kompiliert wird und daher die Umgebung ignoriert, können Sie dennoch relativ sicher sein, dass der Wert korrekt ist. Der Grund dafür ist, dass jede Plattform, die es wert ist, unterschieden zu werden, aufgrund unterschiedlicher ausführbarer Formate neu erstellt werden muss und somit einen neuen GOOSWert hat.


Ich habe versucht, dies auszuführen, aber ich erhalte einen seltsamen Fehler. path_windows.go: 4: 24: PATH_SEPARATOR wurde in diesem Block neu deklariert. vorherige Deklaration bei path_unix.go: 4: 24 Und ich verstehe es einfach nicht ... Bekommt der Compiler es nicht?
Ramon JA Smit

2
@ RamonJ.A.Smit Sie müssen Build-Einschränkungen zu diesen Dateien hinzufügen, wie folgt: path_unix.go sollte haben // +build !windowsund path_windows.go sollte haben // +build windows. Ich habe die Antwort oben bearbeitet, um zu zeigen, wohin sie gehen sollen. Sie müssen vor der packageAnweisung stehen und von einer Leerzeile gefolgt werden, damit sie nicht als Dokumentation für das Paket interpretiert werden.
Tim Lewis

Danke für den zusätzlichen Input! Wird damit spielen. Danke :-)
Ramon JA Smit


0

Ich bin gerade auf die Suche nach etwas anderem gestoßen und habe das Alter dieses Beitrags bemerkt, also werde ich eine aktuellere Ergänzung hinzufügen. Wenn Sie nur versuchen, den richtigen Dateipfad zu verarbeiten, würde ich filepath.Join () verwenden . Es nimmt alle Rätselraten aus OS-Problemen. Wenn Sie mehr als nur einen Dateipfad benötigen, können Sie die Laufzeitkonstanten ( runtime.GOOS& runtime.GOARCH) verwenden: Beispiel für einen Spielplatz

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.