Bagaimana cara membuat daftar semua pengguna dalam grup Linux?


273

Bagaimana cara mendaftar semua anggota grup di Linux (dan mungkin juga unit lainnya)?


1
@ Silmari89, Tidak jika dia ingin melakukannya secara terprogram.
Paul Tomblin

2
Saya baru di sini, saya menemukan bahwa SF ada setelah saya memposting pertanyaan. Saya setuju itu milik SF atau SO.
user323094

5
Heh, tentu saja, sekarang memiliki solusi terprogram, sehingga bisa dibenarkan di sini juga.
Zed

Jawaban:


103

Sayangnya, tidak ada cara yang baik dan portabel untuk melakukan ini yang saya tahu. Jika Anda mencoba mem-parsing / etc / group, seperti yang disarankan orang lain, Anda akan kehilangan pengguna yang memiliki grup itu sebagai grup utama mereka dan siapa saja yang telah ditambahkan ke grup itu melalui mekanisme selain UNIX flat file (yaitu LDAP, NIS, pam-pgsql, dll.).

Jika saya benar-benar harus melakukan ini sendiri, saya mungkin akan melakukannya secara terbalik: gunakan iduntuk mendapatkan grup dari setiap pengguna pada sistem (yang akan menarik semua sumber terlihat ke NSS), dan menggunakan Perl atau sesuatu yang serupa untuk mempertahankan hash tabel untuk setiap kelompok ditemukan mencatat keanggotaan pengguna itu.

Sunting: Tentu saja, ini membuat Anda memiliki masalah serupa: bagaimana cara mendapatkan daftar setiap pengguna pada sistem. Karena lokasi saya hanya menggunakan file datar dan LDAP, saya hanya bisa mendapatkan daftar dari kedua lokasi, tetapi itu mungkin atau mungkin tidak berlaku untuk lingkungan Anda.

Sunting 2: Seseorang yang lewat mengingatkan saya bahwa getent passwdakan mengembalikan daftar semua pengguna pada sistem termasuk yang dari LDAP / NIS / dll., Tetapi getent group masih akan merindukan pengguna yang hanya menjadi anggota melalui entri grup default, sehingga mengilhami saya untuk tulis hack cepat ini.


#!/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
Terima kasih untuk semua yang menjawab. Saya sedang mencari cara portabel untuk melakukannya. Informasi Anda bahwa tidak ada cara yang mudah dan portabel sangat membantu. Anda juga menjelaskan secara terperinci tentang keadaan yang membantu saya memahami masalah lebih dalam, saya menghargai itu dan saya memilih jawaban Anda sebagai yang diterima.
user323094

2
Apakah mungkin bagi Anda untuk menyumbangkan skrip Anda ke yayasan Linux? Ini adalah 2012 dan masih belum ada cara mudah untuk mendapatkan anggota grup. Itulah hal yang membuat saya frustrasi tentang Linux.
Musim dingin

6
Saya menambahkan lisensi mirip ISC untuk Anda, yang harus kompatibel dengan hampir semua grup. Jangan ragu untuk mengirimkannya di mana saja Anda pikir itu akan diterima.
Zed

PAM tidak menyediakan informasi akun. Ini adalah Sakelar Layanan Nama (nsswitch) yang melakukan itu. Tidak semua 'basis data' (penyedia data) akan mendukung pencacahan jadi getent passwdmungkin tidak berfungsi (jika misalnya Anda menggunakan sssd).

Poin valid tentang PAM vs NSS - Saya mengubah referensi. Walaupun saya belum menggunakannya, sssd terlihat seperti pengganti nscd pada pandangan pertama daripada penyedia data yang tepat, dan jika rusak getent passwdsaya akan menganggapnya sebagai bug di sssd.
Zed

239
getent group <groupname>;

Ini portabel di Linux dan Solaris, dan bekerja dengan file grup / kata sandi lokal, NIS, dan konfigurasi LDAP.


43
Tidak menampilkan pengguna yang memiliki grup sebagai grup default mereka.
rlpowell


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

7
Ini akan menjadi cara terbaik, kecuali tutupnya yang tidak dalam instalasi standar Debian. Di Ubuntu ada di paket libuser opsional (bukan yang ada di id-utils dengan nama yang sama). Saya tidak menemukannya di Debian :(
user323094

Bekerja untuk saya di Scientific Linux
blong

pada Debian Wheezy, tutupnya ada pada paket libuser juga
Lluís

2
@JohnMcGehee RHEL seharusnya dipanggil AustereLinux
goelakash

1
'-g' bukan pilihan bagi saya. Saya memiliki id-utils versi 4.6 yang diinstal pada Ubuntu 16.04.
Wilson Biggs

25

Perintah berikut akan mencantumkan semua pengguna milik <your_group_name>, tetapi hanya mereka yang dikelola oleh /etc/groupbasis data, bukan LDAP, NIS, dll. Ini juga berfungsi untuk grup sekunder saja , itu tidak akan mencantumkan pengguna yang memiliki grup yang ditetapkan sebagai utama karena grup utama adalah disimpan sebagai GID(ID grup numerik) dalam file /etc/passwd.

grep <your_group_name> /etc/group

4
Anda dapat grep langsung ke file itu seperti grep <username> / etc / group. Lebih cepat dan lebih murah.
paintbox

16

Perintah berikut akan mencantumkan semua pengguna milik <your_group_name>, tetapi hanya mereka yang dikelola oleh /etc/groupbasis data, bukan LDAP, NIS, dll. Ini juga berfungsi untuk grup sekunder saja , itu tidak akan mencantumkan pengguna yang memiliki grup yang ditetapkan sebagai utama karena grup utama adalah disimpan sebagai GID(ID grup numerik) dalam file /etc/passwd.

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

7
Tidak menampilkan pengguna yang memiliki grup sebagai grup default mereka.
rlpowell

3
Tidak memeriksa NIS dan LDAP.
Paweł Nadolski

12

Script shell berikut akan mengulangi semua pengguna dan hanya mencetak nama-nama pengguna yang dimiliki grup tertentu:

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

Contoh penggunaan:

./script 'DOMAIN+Group Name'

Catatan: Solusi ini akan memeriksa NIS dan LDAP untuk pengguna dan grup (tidak hanya file passwddan group). Ini juga akan mempertimbangkan pengguna akun yang tidak ditambahkan ke grup tetapi memiliki grup yang ditetapkan sebagai grup utama.

Sunting: Menambahkan perbaikan untuk skenario langka di mana pengguna bukan milik grup dengan nama yang sama.

Sunting: ditulis dalam bentuk skrip shell; ditambahkan trueuntuk keluar dengan 0status seperti yang disarankan oleh @Max Chernyak alias hakunin ; dibuang stderruntuk melewati mereka yang sesekali groups: cannot find name for group ID xxxxxx.


Ini bagus, dan sangat ringkas, tetapi ia mencetak nama grup dan juga nama pengguna
andrew lorien

@ andrewlorien, saya harap saya memperbaiki masalah yang Anda sebutkan, jika tidak tolong berikan detail lebih lanjut.
Paweł Nadolski

Cuplikan ini bagus, tetapi mengembalikan kode 1, alasan apa pun mengapa ia tidak mengembalikan 0? Mudah diperbaiki mungkin?
Max Chernyak

@hakunin, itu tidak mengembalikan 0 ketika nama pengguna terakhir bukan milik grup. Anda dapat menambahkan "|| true" di pernyataan akhir untuk selalu mendapatkan 0 jika ini yang Anda inginkan. Anda dapat memeriksa kemudian output untuk melihat apakah ada pengguna yang ditemukan.
Paweł Nadolski

@ PawełNadolski saya menyadari, jadi akhirnya menambahkan ; true. Mengembalikan 0 adalah baik untuk menghindari tersandungnya sistem manajemen konfigurasi Anda (Chef, Ansible, dll).
Max Chernyak

7

Anda dapat melakukannya dalam satu baris perintah:

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

Daftar perintah di atas semua pengguna memiliki groupname sebagai kelompok utama mereka

Jika Anda juga ingin membuat daftar pengguna yang memiliki nama grup sebagai grup kedua, gunakan perintah berikut

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

1
Peringatan: grepakan cocok dengan pengguna yang namanya berisi nomor grup (mis. sc0ttAkan ditampilkan sebagai bagian dari rootgrup). Jika ini merupakan masalah maka gunakan regex :$(getent group <groupname> | cut -d: -f3)\$(cocok dengan tanda koma, id grup, dan akhir baris). (Jangan menambahkan tanda kutip ke regex, atau bash mengeluh.)
Scott Stevens

@ScottS Jatuh resmi. Akan merekomendasikan langkah-langkah yang disarankan
Bhavik

3

hanya sedikit grep and tr:

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

4
Tidak menampilkan pengguna yang memiliki grup sebagai grup default mereka.
rlpowell

3

Implementasi Zed mungkin harus diperluas untuk bekerja pada beberapa UNIX utama lainnya.

Seseorang memiliki akses ke perangkat keras Solaris atau HP-UX ?; tidak menguji kasus-kasus itu.

#!/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";
    }
}

Jika ada cara yang lebih baik untuk membagikan saran ini, harap beri tahu saya; Saya mempertimbangkan banyak hal, dan inilah yang saya pikirkan.


Dikonfirmasi bekerja pada Solaris 10 setelah berganti id -Gnke/usr/xpg4/bin/id -G -n
user667489

3

Saya sudah melakukan ini mirip dengan kode perl di atas, tetapi diganti getent dan id dengan fungsi perl asli. Itu jauh lebih cepat dan harus bekerja di berbagai rasa * nix.

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

Jawaban dengan tautan saja tidak menganggap jawaban yang baik di Stack Overflow. Harap pertimbangkan untuk menghapus ini karena ini tidak memberikan jawaban atas pertanyaan atau menguraikan lebih lanjut tentang bagaimana jawaban ini lebih baik daripada jawaban yang diterima. Atau Anda dapat menambahkan ini sebagai komentar setelah Anda memiliki reputasi yang cukup. Anda selalu dapat mengomentari posting Anda sendiri.
Dipen Shah

2

Ada paket Debian dan Ubuntu yang berguna yang disebut ' anggota ' yang menyediakan fungsionalitas ini:

Deskripsi: Menunjukkan anggota grup; secara default, semua anggota adalah pelengkap grup: sedangkan grup menunjukkan grup yang menjadi milik pengguna tertentu, anggota menunjukkan pengguna yang termasuk dalam grup yang ditentukan.

... Anda dapat meminta anggota utama, anggota sekunder, keduanya pada satu baris, masing-masing pada baris yang berbeda.


Bagaimana jika op menggunakan openwrt?
user2284570

Memang berguna, tetapi sayangnya tidak melaporkan anggota grup domain.
simlev

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

Ini mengembalikan daftar ruang yang dipisahkan dari pengguna yang telah saya gunakan dalam skrip untuk mengisi array.

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

atau

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

0

Berikut ini adalah skrip yang mengembalikan daftar pengguna dari / etc / passwd dan / etc / group yang tidak memeriksa NIS atau LDAP, tetapi itu menunjukkan pengguna yang memiliki grup sebagai grup default mereka Diuji pada Debian 4.7 dan 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

atau sebagai one-liner, Anda dapat memotong dan menempelkan langsung dari sini (ubah nama grup dalam variabel pertama)

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

Di UNIX (tidak seperti GNU / Linux), ada perintah listusers. Lihat halaman manual Solaris untuk daftar pengguna .

Perhatikan bahwa perintah ini adalah bagian dari Proyek Heirloom open-source . Saya berasumsi bahwa itu hilang dari GNU / Linux karena RMS tidak percaya pada grup dan izin. :-)


1
Meskipun tautan ini dapat menjawab pertanyaan, lebih baik untuk memasukkan bagian-bagian penting dari jawaban di sini dan memberikan tautan untuk referensi. Jawaban hanya tautan dapat menjadi tidak valid jika halaman tertaut berubah. - Dari Ulasan
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

Dari situs web Proyek Heirloom: Proyek Heirloom menyediakan implementasi tradisional dari utilitas Unix standar. Dalam banyak kasus, mereka berasal dari bahan Unix asli yang dirilis sebagai Open Source oleh Caldera dan Sun. Antarmuka mengikuti praktik tradisional; mereka umumnya tetap kompatibel dengan Sistem V, meskipun ekstensi yang telah menjadi umum digunakan selama waktu kadang-kadang disediakan. Sebagian besar utilitas juga termasuk dalam varian yang bertujuan untuk kesesuaian POSIX.
Alun Carr

0

Berikut ini adalah skrip awk yang sangat sederhana yang memperhitungkan semua perangkap umum yang tercantum dalam jawaban lain:

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}'

Saya menggunakan ini dengan pengaturan ldap-enabled saya, berjalan pada apa saja dengan getent & awk yang sesuai standar, termasuk solaris 8+ dan hpux.


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

Ini memiliki 3 bagian:

1 - getent group groupnamemenunjukkan baris grup dalam file "/ etc / group". Alternatif untuk cat /etc/group | grep groupname.

2 - awkcetak hanya anggota dalam satu baris yang dipisahkan dengan ','.

3 - trganti ',' dengan baris baru dan cetak setiap pengguna secara berurutan.

4 - Opsional: Anda juga dapat menggunakan pipa lain dengan sort, jika pengguna terlalu banyak.

Salam


0

Saya pikir cara termudah adalah langkah-langkah berikut, Anda tidak perlu menginstal paket atau perangkat lunak apa pun:

  1. Pertama, Anda menemukan GID grup yang ingin Anda ketahui pengguna, ada banyak cara untuk itu: cat / etc / group (kolom terakhir adalah GID) id pengguna (pengguna adalah seseorang yang menjadi milik pengguna grup)

  2. Sekarang Anda akan mendaftar semua pengguna pada file / etc / passwd, tetapi Anda akan menerapkan beberapa filter dengan sekuel perintah berikut untuk mendapatkan hanya anggota grup sebelumnya.

cut -d: -f1,4 / etc / passwd | grep GID (GID adalah angka yang Anda dapatkan dari langkah 1)

perintah cut akan memilih hanya beberapa "kolom" dari file, parameter d menetapkan pembatas ":" dalam kasus ini, parameter -f memilih "bidang" (atau kolom) yang akan ditampilkan 1 dan 4 dalam kasus keluar (pada file / etc / passwd, kolom 1º adalah nama pengguna dan 4º adalah GID dari grup yang dimiliki pengguna), untuk menyelesaikan | grep GID akan memfilter hanya grup (pada kolom 4º) yang Anda telah memilih.


0

Berikut ini satu-baris Python lain yang memperhitungkan keanggotaan grup default pengguna (dari /etc/passwd) serta dari database grup ( /etc/group)

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

Saya sudah mencoba grep 'sample-group-name' /etc/group, yang akan mencantumkan semua anggota grup yang Anda tentukan berdasarkan contoh di sini


1
Grepping /etc/groupsudah ada dalam setidaknya 3 jawaban lain, apa nilai yang ditambahkan oleh jawaban Anda? Juga, semua jawaban lain memiliki komentar bahwa solusi tersebut hanya berfungsi untuk grup sekunder dan juga tidak berfungsi untuk akun yang dikelola oleh LDAP, NIS, dll.
David Ferenczy Rogožan
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.