Ruby:如何从 /var/db/group.db 访问组信息

Ruby: how to access group info from /var/db/group.db

RHEL/CentOS 8.x, Ruby 2.5.5, irb 0.9.6

我们有一个专门的设置,可以将用户和组信息保存在 /usr/local/etc/[user|group] 中,并有一个自定义 Makefile 可以将该信息相应地添加到 /var/db/[group|passwd].db

我试图在登录后 Ruby 中获取用户所属组的列表。

我对这门语言比较陌生,刚刚阅读了 Etc module 的文档,但这似乎只适用于 /etc/ 文件系统。不离谱 tbh.

是否有一种简单的方法可以访问 /var/db 中的 Berkley DB 信息,或者我是否必须遍历 /usr/local/etc/group 文件才能获取此信息?

我怀疑该模块的文档被严重简化、严重过时,或者两者兼而有之。我几乎 100% 确定 Etc 将使用 OS-provided 标准库函数,而不是自行解析系统文件。 (为什么 Ruby 开发人员要为他们支持的每个 OS 的配置文件编写解析器,而不是仅仅调用 POSIX 函数?)

您可以使用 strace 来证实这种怀疑。

如果您查看 Ruby Etc 模块的结构,它会将 1:1 映射到 POSIX 函数:

这里有POSIX函数进行比较:

endgrent, getgrent, setgrent – group database entry functions

在我的例子中,我在 macOS(已经有专门的用户处理)上测试它,但此外,我在我公司的笔记本电脑上测试它,这是 macOS 加入到Microsoft ActiveDirectory 域。 /etc/passwd/etc/group 中甚至都没有提到我的用户帐户及其组,但是,我可以使用 Etc 轻松阅读它们。我很确定 Ruby 开发人员没有实现 ActiveDirector 只是为了适应我个人的奇怪用例,所以它必须使用系统功能。

所以,如果你有,例如a uid 想知道它属于什么组,需要先得到它的名字,然后搜索组。不幸的是,提供的迭代器包装器似乎不支持不提供块 returns 和 Enumerator 的常见习惯用法,因此您必须自己创建一个。

require 'etc'

uid = 0 # for example

username = Etc.getpwuid(uid).name

groups = Etc.enum_for(:group).select {|group| group.mem.include?(username) }

p groups