Listar usuários em todos os grupos unix especificados

4

Existe uma maneira fácil de obter uma lista de usuários que estão em todos grupos especificados?

Por exemplo, se eu tiver os seguintes usuários:

fred - rainbow, dell
jane - hp
zippy - rainbow, hp, dell
george - hp, dell
bungle - rainbow, hp, dell

Eu gostaria de algo assim:

[me@box ~]$ magic "dell,hp"
zippy, george, bungle

ie retornando os usuários que estão tanto na dell quanto na hp.

Se houver várias etapas, tudo bem, embora não seja realmente possível sem ter que recorrer a muitas magias negras do Bash, e é mais rápido fazê-lo em um editor de texto habilitado para RE que também seja bom.

Estou rodando no RHEL4 se isso faz alguma diferença.

    
por Rich 23.02.2011 / 11:29

4 respostas

3

Eu não conheço nenhuma ferramenta fazendo isso, mas é fácil criar scripts.

Primeiro, obtenha a lista dos usuários no sistema e, em seguida, execute groups em cada e, no final, grep nos grupos desejados:

getent passwd | sed 's/:.*$//g' | \
    while read user; do groups $user; done | \
    grep group1 | grep group2
    
por 23.02.2011 / 11:45
4

Isso funciona para dois grupos por vez:

getent group dell hp | cut -d: -f 4 | tr , '\n' | sort | uniq -d | sed ':a;$s/\n/, /g;N;ba'

Coloque-o em uma função com algumas modificações e ele lidará com qualquer número de grupos:

grmagic () {
    getent group "$@" | 
        cut -d: -f 4 | 
        tr , '\n' | 
        sort | 
        uniq -dc | 
        grep "^[[:blank:]]*$#" |
        awk '{all = all d $3; d = ", "} END {print all}'
}

Execute:

$ grmagic dell hp
zippy, george, bungle
$ grmagic dell hp rainbow
zippy, bungle

Uma função que consiste principalmente em um script 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"  }'
}
    
por 23.02.2011 / 12:10
1

Script Python pequeno:

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

Teste:

# 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
    
por 23.02.2011 / 12:05
0

Uma solução bash que leva mais de um usuário por linha e imprime somente grupos exclusivos. A saída normal é um grop por linha, use -c para obter a saída separada por vírgulas.

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

Exemplo de saída:

# ./magic.sh coredump mongodb
audio
cdrom
coredump
dialout
floppy
lpadmin
mongodb
netdev
nogroup
plugdev
powerdev
video

Usando -c :

# ./magic.sh -c coredump mongodb
audio,cdrom,coredump,dialout,floppy,lpadmin,mongodb,netdev,nogroup,plugdev,powerdev,video
    
por 23.02.2011 / 12:40