Bir Linux grubundaki tüm kullanıcılar nasıl listelenir?


273

Linux'ta bir grubun tüm üyelerini (ve muhtemelen diğer birlikleri) nasıl listeleyebilirim?


1
@ Silmari89, Programlı yapmak istiyorsa değil.
Paul Tomblin

2
Burada yeniyim, soruyu gönderdikten hemen sonra SF'nin var olduğunu öğrendim. SF veya SO'ya ait olduğunu kabul ediyorum.
user323094

5
Heh, elbette, şimdi programlı bir çözümü var, bu yüzden burada da haklı olabilir.
Zed

Yanıtlar:


103

Ne yazık ki, bunu yapmanın iyi, taşınabilir bir yolu yok. / Etc / group öğelerini ayrıştırmaya çalışırsanız, başkalarının önerdiği gibi, bu grubu birincil grubu olarak kullanan kullanıcıları ve bu gruba UNIX düz dosyaları (LDAP, NIS, pam-pgsql, vb.).

Bunu kesinlikle kendim yapmak zorunda kalsaydım, muhtemelen tersine yapardım: idsistemdeki her kullanıcının gruplarını almak için kullanın (ki bu, NSS tarafından görülebilir tüm kaynakları çekecektir) ve Perl veya bir hash sağlamak için benzer bir şey kullanın her bir grup için o kullanıcının üyeliğine dikkat çeken bir tablo.

Düzenleme: Tabii ki, bu benzer bir sorun bırakır: sistemdeki her kullanıcının bir listesini almak için nasıl. Konumum yalnızca düz dosyalar ve LDAP kullandığından, her iki konumdan da bir liste alabilirim, ancak bu ortamınız için doğru olabilir veya olmayabilir.

Edit 2: Birisi bana getent passwdLDAP / NIS / vb. Dahil olmak üzere sistemdeki tüm kullanıcıların bir listesini döndüreceğini hatırlattı , ancak getent group yine de sadece varsayılan grup girişi yoluyla üye olan kullanıcıları özleyecek, böylece bana ilham verdi Bu hızlı kesmek yazın.


#!/usr/bin/perl -T
#
# Lists members of all groups, or optionally just the group
# specified on the command line
#
# Copyright © 2010-2013 by Zed Pobre (zed@debian.org or zed@resonant.org)
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#

use strict; use warnings;

$ENV{"PATH"} = "/usr/bin:/bin";

my $wantedgroup = shift;

my %groupmembers;
my $usertext = `getent passwd`;

my @users = $usertext =~ /^([a-zA-Z0-9_-]+):/gm;

foreach my $userid (@users)
{
    my $usergrouptext = `id -Gn $userid`;
    my @grouplist = split(' ',$usergrouptext);

    foreach my $group (@grouplist)
    {
        $groupmembers{$group}->{$userid} = 1;
    }
}

if($wantedgroup)
{
    print_group_members($wantedgroup);
}
else
{
    foreach my $group (sort keys %groupmembers)
    {
        print "Group ",$group," has the following members:\n";
        print_group_members($group);
        print "\n";
    }
}

sub print_group_members
{
    my ($group) = @_;
    return unless $group;

    foreach my $member (sort keys %{$groupmembers{$group}})
    {
        print $member,"\n";
    }
}

3
Cevap için teşekkürler. Bunu yapmak için taşınabilir bir yol arıyordum. Kolay ve taşınabilir bir yol olmadığı bilginiz yardımcı oldu. Ayrıca, sorunu daha derinlemesine anlamama yardımcı olan koşullar hakkında en çok ayrıntı verdiniz, bunu takdir ediyorum ve cevabınızı kabul edilen olarak seçtim.
user323094

2
Senaryonuzu Linux vakfına bağışlamanız mümkün olabilir mi? 2012 ve bir grubun üyelerini almanın kolay bir yolu yok. Beni Linux hakkında sinirlendiren şey bu.
winteck

6
Hemen hemen her grupla uyumlu olması gereken ISC benzeri bir lisans ekledim. Kabul edileceğini düşündüğünüz herhangi bir yere göndermekten çekinmeyin.
Zed

PAM hesap bilgileri sağlamaz. Bunu yapan İsim Hizmet Anahtarıdır (nsswitch). Tüm 'veritabanları' (veri sağlayıcıları) numaralandırmayı desteklemeyeceği getent passwdiçin çalışmayabilir (örneğin, sssd kullanıyorsanız).

PAM vs NSS hakkında geçerli nokta - Referansı değiştirdim. Kullanmasam da, sssd uygun bir veri sağlayıcısı yerine ilk bakışta nscd değiştirme gibi görünüyor ve eğer kırılırsa getent passwdsssd'de bir hata olduğunu düşünürdüm.
Zed

239
getent group <groupname>;

Hem Linux hem de Solaris'te taşınabilir ve yerel grup / şifre dosyaları, NIS ve LDAP yapılandırmaları ile çalışır.


43
Gruba sahip olan kullanıcıları varsayılan grup olarak göstermez.
13:34


39
lid -g groupname | cut -f1 -d'(' 

7
Bu kapak en iyi yol olacaktır, ancak kapak standart bir Debian kurulumunda değildir. Ubuntu'da libuser isteğe bağlı paketindedir (id-utils'te aynı ada sahip olan paket değildir). Debian'da bulamadım :(
user323094

Scientific Linux'ta
çalıştım

Debian Wheezy üzerinde, kapak da libuser paketinde
Lluís

2
@JohnMcGehee RHEL, AustereLinux
goelakash

1
'-g' benim için bir seçenek değil. Ubuntu 16.04'te id-utils sürüm 4.6 yüklü.
Wilson Biggs

25

Aşağıdaki komut, <your_group_name>yalnızca /etc/groupLDAP, NIS vb. Değil, yalnızca veritabanıyla yönetilen kullanıcıları listeler . Ayrıca yalnızca ikincil gruplar için de çalışır , birincil grup olduğu için bu grubu birincil olarak ayarlanmış kullanıcıları listelemez GIDdosyada (sayısal grup kimliği) olarak saklanır /etc/passwd.

grep <your_group_name> /etc/group

4
Doğrudan o dosyaya grep <username> / etc / group gibi grep yapabilirsiniz. Daha hızlı ve daha az ek yük.
paintbox

16

Aşağıdaki komut, <your_group_name>yalnızca /etc/groupLDAP, NIS vb. Değil, yalnızca veritabanıyla yönetilen kullanıcıları listeler . Ayrıca yalnızca ikincil gruplar için de çalışır , birincil grup olduğu için bu grubu birincil olarak ayarlanmış kullanıcıları listelemez GIDdosyada (sayısal grup kimliği) olarak saklanır /etc/passwd.

awk -F: '/^groupname/ {print $4;}' /etc/group

7
Gruba sahip olan kullanıcıları varsayılan grup olarak göstermez.
13:35

3
NIS ve LDAP'yi kontrol etmez.
Paweł Nadolski

12

Aşağıdaki kabuk betiği tüm kullanıcılar arasında yinelenir ve yalnızca belirli bir gruba ait olan kullanıcı adlarını yazdırır:

#!/usr/bin/env bash
getent passwd | while IFS=: read name trash
do
    groups $name 2>/dev/null | cut -f2 -d: | grep -i -q -w "$1" && echo $name
done
true

Kullanım örneği:

./script 'DOMAIN+Group Name'

Not: Bu çözüm NIS ve LDAP'yi kullanıcılar ve gruplar için kontrol eder (sadece passwdve groupdosyalar için değil ). Ayrıca bir gruba eklenmemiş, ancak birincil grup olarak grup ayarlanmış kullanıcıları da dikkate alacaktır.

Düzenleme: Kullanıcının aynı ada sahip gruba ait olmadığı nadir senaryo için düzeltme eklendi.

Düzenleme: kabuk betiği şeklinde yazılmış; @Max Chernyak aka hakunin tarafından önerildiği gibi trueçıkışa eklendi ; bunları atlamak için atılır .0stderrgroups: cannot find name for group ID xxxxxx


Bu harika ve çok özlü, ancak grup adını ve kullanıcı adlarını yazdırır
andrew lorien

@andrewlorien, umarım bahsettiğiniz sorunu çözdüm, değilse lütfen daha fazla ayrıntı sağlayın.
Paweł Nadolski

Bu snippet iyidir, ancak çıkış kodu 1'i döndürür, neden 0 döndürmez? Kolay düzeltme belki?
Max Chernyak

@hakunin, son kullanıcı adı gruba ait olmadığında 0 döndürmez. İstediğiniz buysa, her zaman 0 almak için end deyimine "|| true" ifadesini ekleyebilirsiniz. Daha sonra herhangi bir kullanıcının bulunup bulunmadığını görmek için çıktıyı kontrol edebilirsiniz.
Paweł Nadolski

@ PawełNadolski farkettim, bu yüzden ekleme sona erdi ; true. 0 döndürmek, yapılandırma yönetim sisteminizi (Chef, Ansible, vb.) Devreye sokmamak için iyidir.
Max Chernyak

7

Tek bir komut satırında yapabilirsiniz:

cut -d: -f1,4 /etc/passwd | grep $(getent group <groupname> | cut -d: -f3) | cut -d: -f1

Yukarıdaki komut, grup adı olan tüm kullanıcıları birincil grupları olarak listeler

Ayrıca grup adı olan kullanıcıları ikincil grubu olarak listelemek istiyorsanız , aşağıdaki komutu kullanın

getent group <groupname> | cut -d: -f4 |  tr ',' '\n'

1
Uyarı: grepadı grup numarasını içeren bir kullanıcıyla eşleşir (ör . Grubun bir sc0ttparçası olarak gösterilir root). Bu bir sorunsa, normal ifadeyi kullanın :$(getent group <groupname> | cut -d: -f3)\$(noktalı virgül, grup kimliği ve satırın sonu ile eşleşir). (Normal ifadeye alıntı eklemeyin veya bash şikayet ediyor.)
Scott Stevens

@ScottS Yasal bir pit-fall. Önerilen adımları tavsiye ederim
Bhavik

3

sadece biraz grep ve tr:

$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3

4
Gruba sahip olan kullanıcıları varsayılan grup olarak göstermez.
13:35

3

Zed'in uygulaması büyük olasılıkla diğer büyük UNIX'lerin bazıları üzerinde çalışacak şekilde genişletilmelidir.

Birisi Solaris veya HP-UX donanımına erişebilir mi ?; bu davaları test etmedi.

#!/usr/bin/perl
#
# Lists members of all groups, or optionally just the group
# specified on the command line
#
# Date:         12/30/2013
# Author:       William H. McCloskey, Jr.
# Changes:      Added logic to detect host type & tailor subset of getent (OSX)
# Attribution:
#   The logic for this script was directly lifted from Zed Pobre's work.
#     See below for Copyright notice.
#   The idea to use dscl to emulate a subset of the now defunct getent on OSX
#     came from
#       http://zzamboni.org/\
#         brt/2008/01/21/how-to-emulate-unix-getent-with-macosxs-dscl/
#     with an example implementation lifted from
#       https://github.com/petere/getent-osx/blob/master/getent
#
# Copyright © 2010-2013 by Zed Pobre (zed@debian.org or zed@resonant.org)
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#

use strict; use warnings;

$ENV{"PATH"} = "/usr/bin:/bin";

# Only run on supported $os:
my $os;
($os)=(`uname -a` =~ /^([\w-]+)/);
unless ($os =~ /(HU-UX|SunOS|Linux|Darwin)/)
    {die "\$getent or equiv. does not exist:  Cannot run on $os\n";}

my $wantedgroup = shift;

my %groupmembers;

my @users;

# Acquire the list of @users based on what is available on this OS:
if ($os =~ /(SunOS|Linux|HP-UX)/) {
    #HP-UX & Solaris assumed to be like Linux; they have not been tested.
    my $usertext = `getent passwd`;
    @users = $usertext =~ /^([a-zA-Z0-9_-]+):/gm;
};
if ($os =~ /Darwin/) {
    @users = `dscl . -ls /Users`;
    chop @users;
}

# Now just do what Zed did - thanks Zed.
foreach my $userid (@users)
{
    my $usergrouptext = `id -Gn $userid`;
    my @grouplist = split(' ',$usergrouptext);

    foreach my $group (@grouplist)
    {
        $groupmembers{$group}->{$userid} = 1;
    }
}

if($wantedgroup)
{
    print_group_members($wantedgroup);
}
else
{
    foreach my $group (sort keys %groupmembers)
    {
        print "Group ",$group," has the following members:\n";
        print_group_members($group);
        print "\n";
    }
}

sub print_group_members
{
    my ($group) = @_;
    return unless $group;

    foreach my $member (sort keys %{$groupmembers{$group}})
    {
        print $member,"\n";
    }
}

Bu öneriyi paylaşmanın daha iyi bir yolu varsa, lütfen bana bildirin; Ben birçok yolu düşündüm ve ben de bunu buldum.


Onaylandı değiştirdikten sonra Solaris 10 üzerinde çalışan id -Gniçin/usr/xpg4/bin/id -G -n
user667489

3

Bunu yukarıdaki perl koduna benzer yaptım, ancak yerel perl işlevleriyle getent ve id yerine geçtim. Çok daha hızlıdır ve farklı * nix aromaları üzerinde çalışmalıdır.

#!/usr/bin/env perl

use strict;
my $arg=shift;
my %groupMembers; # defining outside of function so that hash is only built once for multiple function calls

sub expandGroupMembers{
my $groupQuery=shift;
unless (%groupMembers){
    while (my($name,$pass,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire)=getpwent()) {
            my $primaryGroup=getgrgid($gid);
            $groupMembers{$primaryGroup}->{$name}=1;
    }
    while (my($gname,$gpasswd,$gid,$members)=getgrent()) {
            foreach my $member (split / /, $members){
                    $groupMembers{$gname}->{$member}=1;
            }
    }
}
my $membersConcat=join(",",sort keys %{$groupMembers{$groupQuery}});
return "$membersConcat" || "$groupQuery Does have any members";
}
print &expandGroupMembers($arg)."\n";

Yalnızca bağlantı içeren bir yanıt, Yığın Taşması için iyi bir yanıt olarak değerlendirilmez. Lütfen bunu silmeyi düşünün, çünkü bu soruya bir cevap vermez veya bu cevabın kabul edilen cevaptan daha iyi olduğu konusunda daha fazla ayrıntı verir. Ya da yeterli itibara sahip olduğunuzda bunu yorum olarak ekleyebilirsiniz. Her zaman kendi yayınlarınıza yorum yapabilirsiniz.
Dipen Shah

2

Bu işlevselliği sağlayan ' üye ' adında kullanışlı bir Debian ve Ubuntu paketi var :

Açıklama: Bir grubun üyelerini gösterir; varsayılan olarak, tüm üye üyeler grupların tamamlayıcısıdır: gruplar belirtilen bir kullanıcının ait olduğu grupları gösterirken, üyeler belirli bir gruba ait olan kullanıcıları gösterir.

... Birincil üyeler, ikincil üyeler, her ikisinde de ayrı satırlarda isteyebilirsiniz.


Operasyon openwrt kullanıyorsa ne olur?
user2284570

Gerçekten kullanışlı, ancak maalesef etki alanı grubu üyelerini bildirmiyor.
simlev

1
getent group insert_group_name_here | awk -F ':' '{print $4}' | sed 's|,| |g'

Bu, dizileri doldurmak için komut dosyalarında kullandığım boşlukla ayrılmış kullanıcıların bir listesini döndürür.

for i in $(getent group ftp | awk -F ':' '{print $4}' | sed 's|,| |g')
    do
        userarray+=("$i")
    done

veya

userarray+=("$(getent group GROUPNAME | awk -F ':' '{print $4}' | sed 's|,| |g')")

0

Burada, / etc / passwd ve / etc / grubundaki kullanıcıların bir listesini döndüren bir komut dosyasıdır, NIS veya LDAP'yi kontrol etmez, ancak gruba sahip olan kullanıcıları varsayılan grup olarak gösterir Debian 4.7 ve solaris 9

#!/bin/bash

MYGROUP="user"

# get the group ID
MYGID=`grep $MYGROUP /etc/group | cut -d ":" -f3`
if [[ $MYGID != "" ]]
then
  # get a newline-separated list of users from /etc/group 
  MYUSERS=`grep $MYGROUP /etc/group | cut -d ":" -f4| tr "," "\n"`
  # add a newline
  MYUSERS=$MYUSERS$'\n'
  # add the users whose default group is MYGROUP from /etc/passwod 
  MYUSERS=$MYUSERS`cat /etc/passwd |grep $MYGID | cut -d ":" -f1`

  #print the result as a newline-separated list with no duplicates (ready to pass into a bash FOR loop)
  printf '%s\n' $MYUSERS  | sort | uniq
fi

veya tek katmanlı olarak doğrudan buradan kesip yapıştırabilirsiniz (ilk değişkendeki grup adını değiştirin)

MYGROUP="user";MYGID=`grep $MYGROUP /etc/group | cut -d ":" -f3`;printf '%s\n' `grep $MYGROUP /etc/group | cut -d ":" -f4| tr "," "\n"`$'\n'`cat /etc/passwd |grep $MYGID | cut -d ":" -f1`  | sort | uniq

0

UNIX'te (GNU / Linux'un aksine), listusers komutu var. Listeleyiciler için Solaris kılavuz sayfasına bakınız .

Bu komutun açık kaynaklı Heirloom Project'in bir parçası olduğunu unutmayın . GNU / Linux'ta eksik olduğunu varsayıyorum çünkü RMS gruplara ve izinlere inanmıyor. :-)


1
Bu bağlantı soruyu cevaplayabilse de, cevabın temel kısımlarını buraya eklemek ve bağlantıyı referans olarak sağlamak daha iyidir. Bağlantı verilen sayfa değişirse, yalnızca bağlantı yanıtları geçersiz olabilir. - Yorumdan
knuhol

NAME listusers - print a list of user logins SYNOPSIS listusers [-g groups] [-l logins] DESCRIPTION Listusers prints the name and the gecos information of all users known to the system, sorted by username. Valid options are: -g groups Only print the names of users that belong to the given group. Multiple groups are accepted if separated by commas. -l logins Print only user names that match logins. Multiple user names are accepted if separated by commas.
Alun Carr

Heirloom Projesi web sitesinden: Heirloom Projesi, standart Unix yardımcı programlarının geleneksel uygulamalarını sunar. Birçok durumda, Caldera ve Sun tarafından Açık Kaynak olarak yayınlanan orijinal Unix malzemeden türetilmiştir. Arayüzler geleneksel uygulamaları takip eder; zamanla yaygın olarak kullanılan uzantılar bazen sağlansa da, genellikle Sistem V ile uyumlu kalırlar. Çoğu yardımcı program da POSIX uyumluluğunu amaçlayan bir varyanta dahil edilmiştir.
Alun Carr

0

Diğer cevaplarda listelenen tüm yaygın tuzakları dikkate alan çok basit bir awk betiği:

getent passwd | awk -F: -v group_name="wheel" '
  BEGIN {
    "getent group " group_name | getline groupline;
    if (!groupline) exit 1;
    split(groupline, groupdef, ":");
    guid = groupdef[3];
    split(groupdef[4], users, ",");
    for (k in users) print users[k]
  }
  $4 == guid {print $1}'

Bunu ldap özellikli kurulumumla kullanıyorum, solaris 8+ ve hpux da dahil olmak üzere standartlara uygun getent & awk ile çalışır.


0
getent group groupname | awk -F: '{print $4}' | tr , '\n'

Bu 3 bölümden oluşmaktadır:

1 - getent group groupname"/ etc / group" dosyasındaki grubun satırını gösterir. Alternatif cat /etc/group | grep groupname.

2 - awkprint yalnızca ',' ile ayrılmış tek bir satırdaki üyelerdir.

3 - tr',' işaretini yeni bir satırla değiştirin ve her kullanıcıyı arka arkaya yazdırın.

4 - İsteğe bağlı: sortKullanıcılar çok fazla ise, ile başka bir boru da kullanabilirsiniz .

Saygılarımızla


0

Bence en kolay yol aşağıdaki adımlar, herhangi bir paket veya yazılım yüklemenize gerek yok:

  1. İlk olarak, kullanıcıları tanımak istediğiniz grubun GID'sini öğrenirsiniz, bunun için birçok yol vardır: cat / etc / group (son sütun GID'dir) kimlik kullanıcısı (kullanıcı, ait olduğu kişidir. grup)

  2. Şimdi / etc / passwd dosyasındaki tüm kullanıcıları listeleyeceksiniz, ancak yalnızca önceki grubun üyelerini almak için aşağıdaki komut dizisiyle bazı filtreler uygulayacaksınız.

cut -d: -f1,4 / etc / passwd | grep GID (GID, 1. adımdan aldığınız sayıdır)

cut komutu dosyanın sadece bazı "sütunlarını" seçecektir, d parametresi ":" sınırlayıcısını ayarlar, bu durumda, -f parametresi dışarıda (1) ve 4'te gösterilecek "alanları" (veya sütunları) seçer (açık / etc / passwd dosyası, 1º sütunu kullanıcının adı ve 4º, kullanıcının ait olduğu grubun GID'sidir, | grep GID'yi sonlandırmak için yalnızca (4º sütunundaki) grubu filtreleyecektir seçmişti.


0

Burada, kullanıcının varsayılan grup üyeliğini (kimden /etc/passwd) ve grup veritabanından ( /etc/group) dikkate alan başka bir Python tek astarı var

python -c "import grp,pwd; print set(grp.getgrnam('mysupercoolgroup')[3]).union([u[0] for u in pwd.getpwall() if u.pw_gid == grp.getgrnam('mysupercoolgroup')[2]])"

-1

Ben denedim grep 'sample-group-name' /etc/groupbu örneğin dayalı Belirttiğiniz grubun tüm üyelerinin listeler, burada


1
Grepping /etc/groupzaten en az 3 başka cevapta, cevabınız onlara ne değer katıyor ? Ayrıca, tüm bu diğer cevaplar yorumlarınız ikincil gruplar için böyle bir çözüm çalışmaları sadece ve ayrıca yapar vs. LDAP, NIS tarafından yönetilen hesap için değil iş
David Ferenczy Rogožan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.