go proposal: os: Add SysConfigDir() Function

gblwokeq  于 5个月前  发布在  Go
关注(0)|答案(5)|浏览(94)

摘要

本提案建议在Go标准库的os包中添加一个新功能,SysConfigDir()。这个功能将帮助Go应用程序以一致的方式在不同的操作系统中找到系统范围内配置数据的默认目录。

背景

目前,os包中有一个名为UserConfigDir()的函数,用于获取用户特定配置数据所在的目录。但没有类似的函数可以获取系统范围配置数据所在的目录。许多Go应用程序需要这个功能来存储应该在系统上的所有用户之间共享的配置文件。

建议

我建议在os包中添加一个新功能,SysConfigDir()。这个功能将返回系统范围配置数据所在的目录路径。它将在所有支持的操作系统上以相同的方式工作,就像UserConfigDir()一样。它的工作原理将根据操作系统的不同而有所不同,遵循该系统的规范。

理由

我们需要添加SysConfigDir()的原因有:

  1. 一致性:有一种获取系统范围配置目录的标准方法,使开发者的工作变得更简单。无论您使用的是哪种操作系统,它都能保持不变。
  2. 最佳实践:这鼓励开发者遵循管理配置的最佳实践。它引导他们使用正确的目录并避免硬编码路径或冲突等问题。
  3. 用户友好:就像UserConfigDir()一样,SysConfigDir()为开发者提供了一种轻松查找系统范围配置目录的方法,即使在采用不同方法的系统中也是如此。

兼容性

添加SysConfigDir()不会破坏现有的代码。这是一个我们正在添加到os包的新功能,因此它不会影响已经存在的东西。

实现

以下是我们将如何使SysConfigDir()工作的步骤:

  1. 确定您正在使用的操作系统(如Windows、Unix、Plan9)。
  2. 根据该操作系统的方式,使用正确的方法来查找系统范围配置目录。
  3. 返回目录路径,如果无法确定,则返回错误。
vtwuwzda

vtwuwzda1#

这是一个有趣的想法!
你知道Go支持的所有操作系统是否对这个问题有一个明确的答案吗?通过具体说明它在每个操作系统上应该如何表现,或者至少在你熟悉的操作系统子集中的表现,可能会有助于扩展这个提案。
os.UserConfigDir 今天的局限性在于它只返回基本目录是什么,而对于该目录内部预期的命名方案却一无所知。例如,我认为在Windows上,习惯于创建两级子目录,如 Vendor Name\Application Name ,然后在该目录下创建文件,而在macOS上,习惯于使用反向DNS形状的名称,如 org.golangcom.example.appname 。我预计 SysConfigDir 提议的限制也类似,但如果它对 os.UserConfigDir 没有影响,那么也许这并不重要。🤷‍♂️

ldxq2e6h

ldxq2e6h2#

用户配置目录提案用于跨引用 #29960
我也喜欢这个想法,对我来说,这听起来就像是这种功能性需求的适当程度的间接性,如果我们开始对用户如何使用它施加太多限制,我们可能会使整体上它的实用性降低。
也许沿着这些线路,对于系统配置目录会起作用:

// SysConfigDir returns the default root directory to use for system-wide
// configuration data. Applications should use this directory for storing
// configuration files that are accessible system-wide.
//
// On Unix systems, it returns /etc.
// On Darwin, it returns /Library/Preferences.
// On Windows, it returns %ProgramData%.
// On Plan 9, it returns /lib.
//
// If the location cannot be determined, it will return an error.
func SysConfigDir() (string, error) {
	var dir string
	switch runtime.GOOS {
	case "windows":
		dir = os.Getenv("ProgramData")
		if dir == "" {
			return "", errors.New("%ProgramData% is not defined")
		}
	case "darwin":
		dir = "/Library/Preferences"
	case "plan9":
		dir = "/lib"
	default: // Unix
		dir = "/etc"
	}
	return dir, nil
}
osh3o9ms

osh3o9ms3#

@mauri870 我也考虑过在Windows中使用ProgramData环境变量,但是它的文档建议不要这样做:https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-folderlocations-programdata

g2ieeal7

g2ieeal74#

你可以尝试在Windows中使用CSIDL_COMMON_APPDATA常量,需要安装golang.org/x/sys/windows包:

package main

import (
    "fmt"
    "golang.org/x/sys/windows"
)

func main() {
    path, err := windows.KnownFolderPath(windows.FOLDERID_ProgramData, 0)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(path)
}

但是,在这里使用外部包可能会使事情变得更加复杂。

2wnc66cl

2wnc66cl5#

文件夹ID_ProgramData的描述非常符合我们的需求,不确定是否需要在操作系统中引入x/sys/windows,我认为我们需要一个更轻量级的解决方案。
无论如何,似乎每个平台都有一个专门为其准备的文件夹,我们只需要弄清楚如何访问它。
让我们等待看看大家对这个提案有什么看法。
/cc @ianlancetaylor@robpike

相关问题