Як надійно виявити os / платформу в Go


77

Ось те, що я зараз використовую, і, на мою думку, це робить роботу, але повинен бути кращий спосіб:

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

Як бачите, у моєму випадку все, що мені потрібно знати, це як виявити вікна, але я хотів би знати спосіб виявлення будь-якої платформи / ОС.

Грати:

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


2
Поточні версії Windows працюватимуть чудово, використовуючи роздільник Posix, який має значення «/». Вам потрібна зворотна скісна риска лише для сценаріїв bat та старих версій Windows, які не належать до Posix.
Rick-777,

Ви можете визначити "поточний"? Лише за останні кілька тижнів мене спалили з жорстким кодуванням '/' ...
mdwhatcott

2
Windows 95, 98 ME та всі попередні версії вимагають зворотної скісної риски. Windows 2000, NT і пізніше приймають зворотну косу риску та косу риску як еквівалентні. Коса коса риса забезпечує сумісність зі старими версіями, тоді як коса коса риса забезпечує відповідність Posix.
Rick-777

Дякую за роз'яснення @ Rick-777.
mdwhatcott

Відповіді:


145

Виявлення під час компіляції

Якщо ви робите це, щоб мати різні реалізації в залежності від ОС, корисніше мати окремі файли з реалізацією цієї функції та додавати теги збірки до кожного з файлів. Це використовується у багатьох місцях у стандартній бібліотеці, наприклад, у osпакунку .

Ці так звані "обмеження побудови" або "теги побудови" пояснюються тут .

Скажімо, у вас є константа, PATH_SEPARATORі ви хочете, щоб ця платформа залежала, ви зробили б два файли, один для Windows та інший для (unix) відпочинку:

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

Тоді код цих файлів буде таким:

path_windows.go

// +build windows

package project

const PATH_SEPARATOR = '\\'

path_unix.go

// +build !windows

package project

const PATH_SEPARATOR = '/'

Тепер ви можете отримати доступ PATH_SEPARATORдо свого коду та забезпечити його залежність від платформи.

Виявлення під час виконання

Якщо ви хочете визначити операційну систему під час виконання, використовуйте runtime.GOOS змінну:

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

Хоча це компілюється в середовищі виконання і, отже, ігнорує середовище, ви тим не менш можете бути відносно впевненими у правильності значення. Причиною цього є те, що кожна платформа, яку варто виділити, потребує відновлення через різні виконувані формати і, отже, має нове GOOSзначення.


Я намагався запустити це, але я отримую якусь дивну помилку. path_windows.go: 4: 24: PATH_SEPARATOR повторно оголошено в цьому блоці. попереднє оголошення на path_unix.go: 4: 24 І я просто не розумію ... Чи не отримує його компілятор?
Ramon JA Smit

2
@ RamonJ.A.Smit вам потрібно буде додати обмеження збірки до цих файлів, наприклад так: path_unix.go повинен мати // +build !windowsі path_windows.go повинен мати // +build windows. Я відредагував відповідь вище, щоб показати, куди вони повинні йти. Вони повинні packageстояти перед випискою, за ними слід пустий рядок, щоб вони не трактувались як документація до пакету.
Тім Льюїс

Дякуємо за додатковий внесок! Пограє з цим. Дякую :-)
Рамон Дж. Сміт

20

Ви розглядали пакунок виконання? Він має GOOS const: http://golang.org/pkg/runtime/#pkg-constants


2
GOOS, в середовищі виконання, встановлюється під час компіляції і читається без встановлення інструментів Go.
Тайлер Егето

2
@Matt, ти думаєш про змінну середовища. @Tyler розбирає, що з runtime.GOOSних буде працювати нормально, наприклад: play.golang.org/p/0dDIEoFXfx
Нік Крейг-Вуд

0

Я просто наткнувся на це, шукаючи щось інше, і помітив вік цього допису, тому додам ще оновлене доповнення. Якщо ви просто намагаєтесь обробити правильний шлях до файлу, я б використав filepath.Join () . Це бере всі здогади з питань os. Якщо вам потрібно більше, ніж просто шлях до файлу, за допомогою констант виконання ( runtime.GOOS& runtime.GOARCH) - це шлях: приклад ігрового майданчика


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.