25

我正在尝试编写一个脚本,在自己的行上输出每个用户及其组,如下所示:

user1 group1  
user2 group1  
user3 group2  
...  
user10 group6

等等

我正在为此用python编写一个脚本,但想知道SO如何做到这一点。

ps 用任何语言尝试一下,但我更喜欢 python。

编辑:我在 Linux 上工作。Ubuntu 8.10 或 CentOS =)

4

5 回答 5

27

对于 *nix,你有pwdgrp模块。您遍历pwd.getpwall()以获取所有用户。您使用 查找他们的组名grp.getgrgid(gid)

import pwd, grp
for p in pwd.getpwall():
    print p[0], grp.getgrgid(p[3])[0]
于 2009-01-07T19:14:47.487 回答
16

grp模块是你的朋友。查看grp.getgrall()以获取所有组及其成员的列表。

编辑示例:

import grp
groups = grp.getgrall()
for group in groups:
    for user in group[3]:
        print user, group[0]
于 2009-01-07T19:12:27.697 回答
5

python 调用grp.getgrall()只显示本地组,这与调用 getgrouplist c 函数不同,后者会重新运行所有用户,例如 sssd 中由 ldap 支持但已关闭枚举的用户。(就像在 FreeIPA 中一样)。在搜索了在 python 中获取用户所属的所有组的最简单方法后,我发现最好的方法是实际调用getgrouplist c 函数:

#!/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 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 xrange(0, ct):
    gid = grouplist[i]
    print grp.getgrgid(gid).gr_name

获取所有用户的列表以类似地运行此函数需要弄清楚 c 调用是由什么进行的,getent passwd并在 python 中调用它。

于 2018-04-23T10:39:46.813 回答
4

sh/bash:

getent passwd | cut -f1 -d: | while read name; do echo -n "$name " ; groups $name ; done
于 2009-01-07T19:19:11.193 回答
1

一个简单的函数,它能够处理任何这些文件(/etc/passwd 和 /etc/group)的结构。

我相信这段代码可以满足您的需求,具有 Python 内置函数且无需额外模块:

#!/usr/bin/python


def read_and_parse(filename):
    """
        Reads and parses lines from /etc/passwd and /etc/group.

        Parameters

          filename : str
            Full path for filename.
    """
    data = []
    with open(filename, "r") as f:
        for line in f.readlines():
            data.append(line.split(":")[0])
        data.sort()
        for item in data:
            print("- " + item)


read_and_parse("/etc/group")
read_and_parse("/etc/passwd")
于 2016-04-08T20:29:40.177 回答