Як надійно виявити 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.