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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9323834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:38:03  来源:igfitidea点击:

Python: How to get group ids of one username (like id -Gn )

pythonlinux

提问by Ade YU

getpwnamecan only get the gidof a username.

getpwname只能得到gid一个username

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

getgroupscan only get groupsof the script user.

getgroups只能获取groups脚本用户。

import os
myGroupIds = os.getgroups()

How can I get all groupsof one arbitrary username, like the id -Gncommand?

我怎样才能得到所有groups一个任意的username,比如id -Gn命令?

id -Gn `whoami`

采纳答案by Gareth A. Lloyd

#!/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

回答by jserras

The result of id -Gnwhen the user belongs to one or more groups in which several group names map to the same gidmight not be the same as the posted answer. For instance if /etc/groupsis similar to this:

id -Gn当用户属于一个或多个组,其中多个组名映射到同一组时,结果gid可能与发布的答案不同。例如,如果/etc/groups与此类似:

 % ypcat group | grep mygroup 
 mygroup:*:66485:user1,user2,user3,...
 mygroup1:*:66485:user101,user102,user103,...
 mygroup2:*:66485:user201,user202,user203,...
 ...

And if the user is not listed in mygroupbut in mygroup<n>, id -Gnreturns mygroupbut the posted answer returns mygroup<n>.

如果用户未在mygroup但在 中列出mygroup<n>,则id -Gn返回mygroup但发布的答案返回mygroup<n>

It seems that in my environment, because UNIX groups can have hundreds or thousands of users, this is a common group management policy, although I don't know exactly what is the user limit per group and why id -Gnalways returns mygroup.

好像在我的环境中,因为UNIX组可以有成百上千的用户,所以这是一个常见的组管理策略,虽然我不知道每个组的用户限制到底是多少,为什么id -Gn总是返回mygroup.

Nevertheless, with the code below I got a match with id -Gn:

尽管如此,使用下面的代码我得到了匹配id -Gn

import pwd, grp    

def getgroups(user):
    gids = [g.gr_gid for g in grp.getgrall() if user in g.gr_mem]
    gid = pwd.getpwnam(user).pw_gid
    gids.append(grp.getgrgid(gid).gr_gid)
    return [grp.getgrgid(gid).gr_name for gid in gids]

回答by cs_alumnus

If you want the current users' groups.

如果您想要当前用户的组。

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

os.getgroups() returns the list of gids of the current user.

os.getgroups() 返回当前用户的 gid 列表。

grp.getgrgid(g) returns details about a group

grp.getgrgid(g) 返回有关组的详细信息

回答by Jens Timmerman

The only way I found to make this work correctly when having users non local to the system (e.g. ldap, sssd+ldap, freeIPA) without calling id in a subprocess is by calling the getgrouplistc function (which is called by id eventually after going trough some abstractions):

当用户非系统本地(例如 ldap、sssd+ldap、freeIPA)而不在子进程中调用 id 时,我发现使此功能正常工作的唯一方法是调用getgrouplistc 函数(它在通过后最终由 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 enought?
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(user.pw_name, user.pw_gid, byref(grouplist), byref(ngrouplist))

# if 50 groups was not enought 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 xrange(0, ct):
    gid = grouplist[i]
    print grp.getgrgid(gid).gr_name