如何可靠地检测 Go 中的操作系统/平台

问题描述 投票:0回答:10

这是我目前正在使用的,我认为它可以完成工作,但必须有更好的方法:

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

如您所见,就我而言,我需要知道的是如何检测窗口,但我想知道检测任何平台/操作系统的方法。

播放:

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

operating-system go
10个回答
198
投票

编译时检测

如果您这样做是为了根据操作系统有不同的实现,则更有用 拥有包含该功能实现的单独文件,并向每个文件添加构建标签 文件的数量。标准库中的许多地方都使用了它,例如

os
包中

这些所谓的“构建约束”或“构建标签”在here有解释。

假设您有常量

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
值。


23
投票

你看过运行时包吗?它有一个 GOOS const:http://golang.org/pkg/runtime/#pkg-constants


11
投票

现在是 2022 年,go 1.18+ 的正确答案是:

在运行时你想要:

if runtime.GOOS == "windows" {
  // windows specific code here...
}

如果需要确定文件系统路径分隔符

用途:

os.PathSeparator

示例:

  • c:\程序文件
  • /usr/local/bin

如果您需要

PATH
环境变量使用的路径列表分隔符

用途:

os.PathListSeparator

示例:

  • /usr/local/bin:/usr/local:
  • “C:\windows”;“c:\windows\system32”;

2
投票

由于这是一个较旧的问题和答案,我找到了另一个解决方案。

您可以简单地使用 os 包中定义的常量。这个常量返回一个

rune
所以你还需要使用字符串转换。

string(os.PathSeparator)
string(os.PathListSeparator)

示例:https://play.golang.org/p/g6jnF7W5_pJ


2
投票

使用

path

package main
  
// Importing fmt and path/filepath
import (
    "fmt"
    "path/filepath"
)
  
// Calling main
func main() {
    fmt.Println(filepath.Join("/", "/")) // out: /
    fmt.Println(filepath.Join(""))// out: 
    fmt.Println(filepath.Join("dirname", "dirsubname")) // out: dirname/subdirname
    fmt.Println(filepath.Join(".")) // out: .
  
}

或使用

GOOS
:

os := runtime.GOOS
    switch os {
    case "windows":
        fmt.Println("Windows")
    case "darwin":
        fmt.Println("MAC operating system")
    case "linux":
        fmt.Println("Linux")
    default:
        fmt.Printf("%s.\n", os)
    }

1
投票

我只是偶然发现这个寻找其他东西,并注意到这篇文章的年龄,所以我将添加更多更新的内容。如果您只是想处理正确的文件路径,我会使用 filepath.Join()。它消除了操作系统问题中的所有猜测。如果除了文件路径之外还需要更多内容,可以使用运行时常量(

runtime.GOOS
&
runtime.GOARCH
):playground 示例


1
投票

我在 Go 1.17.1 中进行了测试,它确实对我有用。

package main

import (
        "fmt"
        "runtime"
)
func main(){
        fmt.Println(runtime.GOOS)
}

Output:
darwin

0
投票

关于检测平台,您可以使用Distribution Detector项目来检测正在运行的Linux发行版。


0
投票

@nemo 的第一个答案是最合适的,我只是想指出,如果您当前是 gopls 语言服务器的用户,则 build 标签 可能无法按预期工作。

到目前为止还没有解决方案或解决方法,您最多可以做的就是更改编辑器的 lsp 配置(vscode、neovim、emacs 等)以选择构建标签,以便能够使用该标签编辑文件而不会出现错误。 使用其他标签编辑文件将不起作用,并且尝试选择多个标签也会失败。 这是该问题目前的进展github@go/x/tools/gopls


0
投票

我找到了这个库,完成了工作。 https://github.com/matishsiao/goInfo

© www.soinside.com 2019 - 2024. All rights reserved.