Python:如何获取一个用户名的组ID(类似于id -Gn)

33 投票
5 回答
29505 浏览
提问于 2025-04-17 13:09

getpwname 只能获取某个 用户名gid(组ID)。

import pwd
myGroupId = pwd.getpwnam(username).pw_gid

getgroups 只能获取当前脚本用户的 groups(组)。

import os
myGroupIds = os.getgroups()

我该如何获取一个任意的 用户名 的所有 groups,就像 id -Gn 命令那样?

id -Gn `whoami`

5 个回答

9

我找到的唯一方法是,当用户不在本地系统上时(比如使用ldap、sssd+ldap或freeIPA),想要正确工作而不通过子进程调用id,就是调用这个getgrouplist的C语言函数(这个函数最终会被id调用,只不过经过了一些抽象处理):

#!/usr/bin/python

import grp, pwd, os
from ctypes import *
from ctypes.util import find_library

libc = cdll.LoadLibrary(find_library('libc'))

getgrouplist = libc.getgrouplist
# 50 groups should be enough, if not, we'll repeat the request with the correct nr bellow
ngroups = 50
getgrouplist.argtypes = [c_char_p, c_uint, POINTER(c_uint * ngroups), POINTER(c_int)]
getgrouplist.restype = c_int32

grouplist = (c_uint * ngroups)()
ngrouplist = c_int(ngroups)

user = pwd.getpwuid(2540485)

ct = getgrouplist(bytes(user.pw_name, 'UTF-8'), user.pw_gid, byref(grouplist), byref(ngrouplist))

# if 50 groups was not enough this will be -1, try again
# luckily the last call put the correct number of groups in ngrouplist
if ct < 0:
    getgrouplist.argtypes = [c_char_p, c_uint, POINTER(c_uint *int(ngrouplist.value)), POINTER(c_int)]
    grouplist = (c_uint * int(ngrouplist.value))()
    ct = getgrouplist(user.pw_name, user.pw_gid, byref(grouplist), byref(ngrouplist))

for i in range(0, ct):
    gid = grouplist[i]
    print(grp.getgrgid(gid).gr_name)
14

如果你想查看当前用户所属的组。

import os, grp
[grp.getgrgid(g).gr_name for g in os.getgroups()]

os.getgroups() 这个函数会返回当前用户的组ID列表。

grp.getgrgid(g) 这个函数可以用来获取某个组的详细信息。

36

下面的内容是针对只关心本地用户的情况,如果你想用它来处理像 sssd 这种依赖目录服务器的情况(比如 ldap),那就不适用了。

#!/usr/bin/env python

import grp, pwd 

user = "myname"
groups = [g.gr_name for g in grp.getgrall() if user in g.gr_mem]
gid = pwd.getpwnam(user).pw_gid
groups.append(grp.getgrgid(gid).gr_name)
print groups

撰写回答