如何在Go中可靠地检测os/platform

ct3nt3jp  于 2023-05-20  发布在  Go
关注(0)|答案(9)|浏览(187)

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

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

正如你所看到的,在我的情况下,我需要知道的是如何检测窗口,但我想知道如何检测任何平台/操作系统。
播放:
http://play.golang.org/p/r4lYWDJDxL

8e2ybdfx

8e2ybdfx1#

编译时检测

如果您这样做是为了根据操作系统有不同的实现,那么使用单独的文件来实现该功能并为每个文件添加构建标记会更有用。这在标准库中的许多地方都有使用,例如in the os package
这些所谓的“构建约束”或“构建标签”在这里解释。
假设你有一个常量PATH_SEPARATOR,并且你希望它与平台相关,你会创建两个文件,一个用于Windows,一个用于(UNIX)rest:

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

tgabmvqs

tgabmvqs2#

你看过runtime包了吗?它有一个GOOS常量:http://golang.org/pkg/runtime/#pkg-constants

lyr7nygr

lyr7nygr3#

现在是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”;
evrscar2

evrscar24#

因为这是一个古老的问题和答案,我找到了另一个解决方案。
您可以简单地使用os包中定义的常量。这个常量返回一个rune,所以你也需要使用字符串转换。

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

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

w1jd8yoj

w1jd8yoj5#

我只是偶然发现了这个寻找其他的东西,并注意到这篇文章的年龄,所以我会添加一个更更新的补充。如果你只是想处理正确的文件路径,我会使用filepath.Join()。它采取了所有的猜测出操作系统的问题。如果你需要更多,而不仅仅是filepath,使用运行时常量(runtime.GOOS & runtime.GOARCH)是一种方法:playground example

oxcyiej7

oxcyiej76#

我在Go 1.17.1中进行了测试,这对我来说真的很有效。

package main

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

Output:
darwin
d4so4syb

d4so4syb7#

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

ibps3vxo

ibps3vxo8#

来自@nemo的第一个答案是最合适的,我只是想指出,如果你目前是gopls语言服务器的用户,构建标签可能无法按预期工作。
到目前为止,还没有解决方案或变通方法,你最多可以做的就是改变你的编辑器的lsp配置(vscode,neovim,emacs等),选择一个build标签,以便能够使用该标签编辑文件而不会出错。使用另一个标签编辑文件将不起作用,并且尝试选择多个标签也会失败。这是问题github@go/x/tools/gopls的当前进度

ufj5ltwl

ufj5ltwl9#

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

相关问题