21.3. grp — Unix 用户组数据库
目的:从 Unix 用户组数据库读取用户组数据
grp
模块用于从 Unix 用户组数据库(通常是 /etc/group
)获取用户组信息。以命名元组形式返回用户组信息的属性字段。
序号 | 属性 | 含义 |
---|---|---|
0 | gr_name |
用户组名称 |
1 | gr_passwd |
用户组密码,如果有(加密形式) |
2 | gr_gid |
用户组ID(整数) |
3 | gr_mem |
组成员名称 |
用户组名称和密码是字符串,组ID是整数,组成员是字符串列表。
获取所有组信息
这个示例打印所有 「真」 用户组信息,包括组成员( 「真」 用户组指名称不是以 _
开头的用户组)。加载整个密码数据库,使用 getgrall()
。
grp_getgrall.py
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('_')
}
print(len(interesting_groups.keys()))
# 找出某些字段的最大长度
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()):
# 格式化组成员,使其换行时保持在这一列的开头,
# 即从第二列开始要有额外的缩进
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))
返回值是未排序的列表,所以在打印之前要先排序。
$ python3 grp_getgrall.py
34
Name GID Members
------------------------------- ----------- -------------------
accessibility 90
admin 80 root
authedusers 50
bin 7
certusers 29 root, _jabber,
_postfix, _cyrus,
_calendar, _dovecot
com.apple.access_disabled 396
com.apple.access_ftp 395
com.apple.access_screensharing 398
com.apple.access_sessionkey 397
com.apple.access_ssh 399
com.apple.sharepoint.group.1 701 dhellmann
consoleusers 53
daemon 1 root
dialer 68
everyone 12
group 16
interactusers 51
kmem 2 root
localaccounts 61
mail 6 _teamsserver
netaccounts 62
netusers 52
network 69
nobody 4294967294
nogroup -1
operator 5 root
owner 10
procmod 9 root
procview 8 root
staff 20 root
sys 3 root
tty 4 root
utmp 45
wheel 0 root
用户所属的用户组
另一个常见任务是打印用户所属的所有用户组:
grp_groups_for_user.py
import grp
username = 'dhellmann'
group_names = set(
g.gr_name
for g in grp.getgrall()
if username in g.gr_mem
)
print(username, 'belongs to:', ', '.join(sorted(group_names)))
用户组集合在打印前先排序。
$ python3 grp_groups_for_user.py
dhellmann belongs to: _appserveradm, _appserverusr, _lpadmin, ad
min, com.apple.sharepoint.group.1
根据名称查找用户组
类似 pwd
,也可以根据组名称或组ID查找用户组信息。
grp_getgrnam.py
import grp
name = 'admin'
info = grp.getgrnam(name)
print('Name :', info.gr_name)
print('GID :', info.gr_gid)
print('Password:', info.gr_passwd)
print('Members :', ', '.join(info.gr_mem))
admin
用户组有两个成员:
$ python3 grp_getgrnam.py
Name : admin
GID : 80
Password: *
Members : root, dhellmann
根据ID查找用户组
根据当前进程确定用户组,使用 getgrgid()
和 os.getgid()
。
grp_getgrgid_process.py
import grp
import os
gid = os.getgid()
group_info = grp.getgrgid(gid)
print('Currently running with GID={} name={}'.format(
gid, group_info.gr_name))
$ python3 grp_getgrgid_process.py
Currently running with GID=20 name=staff
根据文件权限获取用户组信息,使用 os.stat()
的返回值。
grp_getgrgid_fileowner.py
import grp
import os
filename = 'grp_getgrgid_fileowner.py'
stat_info = os.stat(filename)
owner = grp.getgrgid(stat_info.st_gid).gr_name
print('{} is owned by {} ({})'.format(
filename, owner, stat_info.st_gid))
文件(目录)状态信息包括所有者和权限。
$ python3 grp_getgrgid_fileowner.py
grp_getgrgid_fileowner.py is owned by staff (20)
参见如下
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。