我正在尝试编写一个脚本,在自己的行上输出每个用户及其组,如下所示:
user1 group1
user2 group1
user3 group2
...
user10 group6
等等
我正在为此用python编写一个脚本,但想知道SO如何做到这一点。
ps 用任何语言尝试一下,但我更喜欢 python。
编辑:我在 Linux 上工作。Ubuntu 8.10 或 CentOS =)
该grp
模块是你的朋友。查看grp.getgrall()
以获取所有组及其成员的列表。
编辑示例:
import grp
groups = grp.getgrall()
for group in groups:
for user in group[3]:
print user, group[0]
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 中调用它。
sh/bash:
getent passwd | cut -f1 -d: | while read name; do echo -n "$name " ; groups $name ; done
一个简单的函数,它能够处理任何这些文件(/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")