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 函数:
Etc::gegtrent
: 获取下一个组条目。
Etc::endgtrent
: 停止迭代组。
Etc::settrent
: 重置迭代。
这里有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
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 函数:
Etc::gegtrent
: 获取下一个组条目。Etc::endgtrent
: 停止迭代组。Etc::settrent
: 重置迭代。
这里有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