在/ nix命令行实用程序中保存首选项文件的位置/方式?

时间:2012-06-29 22:36:35

标签: linux macos unix

我正在编写一个小命令行实用程序。它应该能够在OSX,UNIX和Linux上运行。

它需要在某处保存一些首选项,例如在一个小的YAML配置文件中。 哪个人会保存这样的文件?

语言:Python 2.7
操作系统:* nix

4 个答案:

答案 0 :(得分:4)

通常,这些文件会像〜/ .rc一样(例如:〜/ .hgrc)。如果您需要大量配置设置,这可以是文件的路径,也可以是目录。

有关详细说明,请参阅http://www.linuxtopia.org/online_books/programming_books/art_of_unix_programming/ch10s03.html

答案 1 :(得分:3)

如果您的应用程序名为“someapp”,则将配置保存在$HOME/.someapp等文件中。如果您愿意,可以为配置文件提供扩展名。如果您认为您的应用可能有多个配置文件,则可以使用目录$HOME/.someapp并在其中创建常规命名(非隐藏)文件。

答案 2 :(得分:3)

我会避免将文件放在~目录中,因为它已经完全充满了垃圾。最近的趋势,至少在ubuntu上,是使用~/.config/<appname>/来表示你需要的任何点文件。我非常喜欢那种惯例。

答案 3 :(得分:1)

许多跨平台工具在OS X上使用与在Linux(以及其他POSIX /非Windows平台)上相同的路径。使用POSIX位置的主要优点是不需要保存几行代码,而是节省了对Mac特定指令的需求,并允许Mac用户从社区中的linux用户那里获得帮助(无需翻译他们的建议) )。

另一种选择是将它们放在〜/ Library下的“Mac友好”位置。使用Mac位置的主要优点基本上是“Apple这么说” - 无论你打算沙箱代码,在这种情况下主要的优点是你可以这样做。

如果您选择使用库位置,则应阅读文件系统编程指南中的About the OS X File SystemOS X Library Directory Details,但这是简短版本:

  • 几乎所有内容:使用您的应用程序名称或软件包ID创建一个子目录(除非您不打算设置软件包ID,否则您将获得org.python.python,这是您不想要的......)在〜/ Library / Application Support下。理想情况下,您应该使用诸如 - [NSFileManager URLForDirectory:inDomain:properForURL:create:error:]之类的API来获取路径;如果没有,你必须手动处理本地化,沙盒容器等事情。
  • 任何可以轻松重新创建的东西(因此不需要备份,迁移等):〜/ Library / Caches的同名子目录。
  • 首选项:改为使用NSUserDefaults或CFPreferences API。如果您使用自己的格式,那么“旧”的处理方式是在〜/ Library / Preferences下创建一个以您的应用程序名称或包ID命名的子目录,并将您的文件放入其中。 Apple不再推荐这样做,但并不真正推荐替代方案(缺少“使用CFPreferences,该死!”);许多应用程序(例如,Aquamacs)仍以旧方式执行,但其他应用程序却假装它们不是首选项并将它们存储在应用程序支持下。

在Python中,这可以如下工作(省略错误处理,并假设您按名称进行而不是为自己设置包ID):

from Foundation import *
fm = NSFileManager.defaultManager()
appsupport = (fm.URLForDirectory_inDomain_appropriateForURL_create_error_(
  NSApplicationSupportDirectory, NSUserDomainMask, None, True, None)[0].
  URLByAppendingPathComponent_isDirectory_(
  appname, True))
caches = (fm.URLForDirectory_inDomain_appropriateForURL_create_error_(
  NSCachesDirectory, NSUserDomainMask, None, True, None)[0].
  URLByAppendingPathComponent_isDirectory_(
  appname, True))
prefs = NSUserDefaults.persistentDomainForName_(appname)