Есть ли простой способ получить список пользователей, которые все указанные группы?
Например, если у меня есть следующие пользователи:
fred - rainbow, dell
jane - hp
zippy - rainbow, hp, dell
george - hp, dell
bungle - rainbow, hp, dell
Хотелось бы примерно такого:
[me@box ~]$ magic "dell,hp"
zippy, george, bungle
т.е. возвращение пользователей, которые работают как в dell, так и в hp.
Если это несколько шагов, это нормально, хотя если это невозможно без использования большого количества черной магии Bash, и это быстрее сделать в текстовом редакторе с поддержкой RE, что тоже нормально.
Я работаю на RHEL4, если это имеет значение.
Это работает одновременно для двух групп:
getent group dell hp | cut -d: -f 4 | tr , '\n' | sort | uniq -d | sed ':a;$s/\n/, /g;N;ba'
Поместите его в функцию с некоторыми изменениями, и она будет обрабатывать любое количество групп:
grmagic () {
getent group "$@" |
cut -d: -f 4 |
tr , '\n' |
sort |
uniq -dc |
grep "^[[:blank:]]*$#" |
awk '{all = all d $3; d = ", "} END {print all}'
}
Запустить его:
$ grmagic dell hp
zippy, george, bungle
$ grmagic dell hp rainbow
zippy, bungle
Функция, состоящая в основном из сценария AWK:
grmagic () {
getent group "$@" |
awk -F: -v "c=$#" '{
split($4, a, ",");
for (i in a) n[a[i]]++
}
END {
for (i in n)
if (n[i] == c) {
printf d i; d=", "
};
printf "\n" }'
}
Я не знаю ни одного инструмента для этого, но его легко написать.
Сначала получите список пользователей в системе, затем запустите groups
на каждом и в конце, grep
по желаемым группам:
getent passwd | sed 's/:.*$//g' | \
while read user; do groups $user; done | \
grep group1 | grep group2
Небольшой скрипт на Python:
#!/usr/bin/python
import subprocess,sys
group={}
for user in sys.argv[1:]:
group[user] = set(subprocess.Popen("id -nG %s"%user, stdout=subprocess.PIPE, shell=True).stdout.read().split())
for g in group[sys.argv[1]] & group[sys.argv[2]]:
print g
Тест:
# id user1
uid=1001(user1) gid=1001(user1) groups=1001(user1),1004(us1),1005(dell)
# id user2
uid=1002(user2) gid=1002(user2) groups=1002(user2),1004(us1),1005(dell)
# ./test.py user1 user2
dell
us1
Решение bash, которое требует более одного пользователя на строку и выводит только уникальные группы. Нормальный вывод - одна попытка на строку, используйте -c
чтобы получить вывод через запятую.
#!/bin/bash
\unalias -a
if [ $# -lt 1 ]
then
echo "Need at least one user" 1>&2
fi
RESULT=''
COMMA=0
while [ $# -gt 0 ]
do
if [ $1 == '-c' ]
then
COMMA=1
else
RESULT="$RESULT $(id -Gn $1)"
fi
shift
done
if [ $COMMA -eq 0 ]
then
echo $RESULT |tr ' ' '\n'| sort -u
else
echo $RESULT |tr ' ' '\n' | sort -u |tr '\n' ', ' |sed 's/.$//g'
echo
fi
Пример вывода:
# ./magic.sh coredump mongodb
audio
cdrom
coredump
dialout
floppy
lpadmin
mongodb
netdev
nogroup
plugdev
powerdev
video
С помощью -c
:
# ./magic.sh -c coredump mongodb
audio,cdrom,coredump,dialout,floppy,lpadmin,mongodb,netdev,nogroup,plugdev,powerdev,video