如何在 Go 中可靠地检测操作系统/平台
Posted
技术标签:
【中文标题】如何在 Go 中可靠地检测操作系统/平台【英文标题】:How to reliably detect os/platform in Go 【发布时间】:2013-11-19 18:52:17 【问题描述】:这是我目前正在使用的,我认为它可以完成工作,但必须有更好的方法:
func isWindows() bool
return os.PathSeparator == '\\' && os.PathListSeparator == ';'
如您所见,就我而言,我只需要知道如何检测窗口,但我想知道检测任何平台/操作系统的方法。
播放:
http://play.golang.org/p/r4lYWDJDxL
【问题讨论】:
当前版本的 Windows 可以使用 Posix 分隔符(即“/”)正常运行。对于 bat 脚本和旧的非 Posix 版本的 Windows,您只需要反斜杠。 你能定义“当前”吗?在过去的几周里,我被硬编码“/”烧死了…… Windows 95、98 ME 和所有早期版本都需要反斜杠。 Windows 2000、NT 和更高版本接受反斜杠和正斜杠作为等效项。反斜杠提供与旧版本的兼容性,而正斜杠提供 Posix 合规性。 感谢@Rick-777 的澄清。 【参考方案1】:编译时检测
如果您这样做是为了根据操作系统有不同的实现,则更有用的是
具有具有该功能实现的单独文件,并为每个文件添加构建标签
的文件。这在标准库中的许多地方都有使用,例如in the os
package。
这些所谓的“构建约束”或“构建标签”解释为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
值。
【讨论】:
我试图运行它,但我得到了一些奇怪的错误。 path_windows.go:4:24: PATH_SEPARATOR 在此块中重新声明。 path_unix.go:4:24 的先前声明而我就是不明白...编译器不明白吗? @RamonJ.A.Smit 你需要像这样向这些文件添加构建约束:path_unix.go 应该有// +build !windows
和 path_windows.go 应该有 // +build windows
。我编辑了上面的答案以显示他们应该去哪里。它们必须出现在 package
语句之前,并且后跟一个空行,因此它们不会被解释为包的文档。
感谢您的额外意见!会玩这个。谢谢:-)
@TimLewis 无论出于何种原因,我都无法让它工作。我在 Windows 上,我在 data_windows.go
中的 GetData
函数被“重新声明”,因为 data_unix.go
中的 GetData
。在 package
语句之前和之后的空行都具有适当的构建约束(data_windows.go
具有 +build windows
和 data_unix.go
具有 +build !windows
),但它仍然不起作用。有什么想法吗?
哦,我明白了问题所在,我的命令是 go build -o ... cli/*.go
,因此它正在构建所有 go 文件,而不管构建约束如何。我把它改成了go build -o ... ./cli
,它起作用了。【参考方案2】:
你看过运行时包吗?它有一个 GOOS 常量:http://golang.org/pkg/runtime/#pkg-constants
【讨论】:
GOOS,在运行时包中,在编译时设置,无需安装 Go 工具即可读取。 @Matt 您正在考虑环境变量。 @Tyler 是runtime.GOOS
的东西,它可以正常工作,例如:play.golang.org/p/0dDIEoFXfx【参考方案3】:
我只是偶然发现了这个寻找别的东西,并注意到这篇文章的年龄,所以我会添加一个更新的补充。如果您只是想处理正确的文件路径,我会使用filepath.Join()。它消除了操作系统问题的所有猜测。如果您需要更多内容,而不仅仅是文件路径,则可以使用运行时常量(runtime.GOOS
和runtime.GOARCH
):playground example
【讨论】:
【参考方案4】:由于这是一个较旧的问题和答案,我找到了另一个解决方案。
您可以简单地使用os 包中定义的常量。此 const 返回 rune
,因此您还需要使用字符串转换。
string(os.PathSeparator)
string(os.PathListSeparator)
示例:https://play.golang.org/p/g6jnF7W5_pJ
【讨论】:
这个答案没有显示如何检测平台。本题使用 os.PathSeparator 和 os.PathListSeparator 来检测 Windows。【参考方案5】:我在 Go 1.17.1 中进行了测试,它确实对我有用。
package main
import (
"fmt"
"runtime"
)
func main()
fmt.Println(runtime.GOOS)
Output:
darwin
【讨论】:
同样的答案在这里:***.com/a/19847766/1517394【参考方案6】:关于检测平台,您可以使用Distribution Detector project 来检测正在运行的Linux 发行版。
【讨论】:
以上是关于如何在 Go 中可靠地检测操作系统/平台的主要内容,如果未能解决你的问题,请参考以下文章