【python 内置模块】grp

2024-01-20 00:00:00

目录:

grp 模块提供了访问 Unix 用户组数据库 (通常是 /etc/group 文件) 的接口, 允许开发者通过组名或组 ID 查询用户组的详细信息,对于系统管理、权限控制和文件操作等场景非常有用。

grp.getgrnam(name)

根据给定的组名称返回对应的组数据库条目, 如果指定的组名不存在, 则会引发 KeyError 异常。

import grp

group_name = 'admin'
try:
    info = grp.getgrnam(group_name)
    print('Name    :', info.gr_name)
    print('GID     :', info.gr_gid)
    print('Password:', info.gr_passwd)
    print('Members :', ', '.join(info.gr_mem))
except KeyError:
    print(f"组 '{group_name}' 不存在。")

grp.getgrgid(gid)

根据给定的数字组 ID 返回对应的组数据库条目。如果找不到, 同样会引发 KeyError。

获取当前进程的组信息:

import grp
import os

gid = os.getgid()
group_info = grp.getgrgid(gid)
print(f'当前进程运行在 GID={gid} 的组下,组名为: {group_info.gr_name}')

获取文件所属组信息:

import grp
import os

filename = 'example.py'
stat_info = os.stat(filename)
owner_group_name = grp.getgrgid(stat_info.st_gid).gr_name
print(f'文件 {filename} 的所属组是 {owner_group_name} (GID={stat_info.st_gid})')

grp.getgrall()

返回所有可用的组数据库条目,字段含义如下:

  • gr_name 组名
  • gr_passwd 组密码
  • gr_gid 组 ID
  • gr_mem 组成员列表

示例: 列出所有非系统组(名称不以 _ 开头)并格式化输出。

import grp
import textwrap

# 获取所有组
all_groups = grp.getgrall()
# 筛选掉可能以 '_' 开头的系统组
interesting_groups = {
    g.gr_name: g
    for g in all_groups
    if not g.gr_name.startswith('_')
}

# 计算各列最大宽度
name_length = max(len(k) for k in interesting_groups) + 1
gid_length = max(len(str(u.gr_gid)) for u in interesting_groups.values()) + 1
members_width = 19

# 定义格式化字符串并打印表头
fmt = ' '.join(['{:<{name_length}}',
                '{:{gid_length}}',
                '{:<{members_width}}',
                ])
print(fmt.format('Name', 'GID', 'Members',
                 name_length=name_length,
                 gid_length=gid_length,
                 members_width=members_width))
print('-' * name_length, '-' * gid_length, '-' * members_width)

# 打印每个组的信息
prefix = ' ' * (name_length + gid_length + 2)
for name, g in sorted(interesting_groups.items()):
    # 使用 textwrap 处理成员列表,使其在换行时保持列对齐
    members = textwrap.fill(
        ', '.join(g.gr_mem),
        initial_indent=prefix,
        subsequent_indent=prefix,
        width=members_width + len(prefix),
    ).strip()
    print(fmt.format(g.gr_name, g.gr_gid, members,
                     name_length=name_length,
                     gid_length=gid_length,
                     members_width=members_width))

查找指定用户所属的组

import grp

username = 'dkvirus'
group_names = set(
    g.gr_name
    for g in grp.getgrall()
    if username in g.gr_mem
)
print(f'{username} 属于以下组: {", ".join(sorted(group_names))}')

注意:此方法仅能查出用户作为 “附加成员” 被明确列在 /etc/group 文件中的组。用户的主组(由 pwd 模块中 pw_gid 定义)通常不在此列表中,需要额外处理。

返回首页

本文总阅读量  次
皖ICP备17026209号-3
总访问量: 
总访客量: