Bagaimana cara mendaftar semua anggota grup di Linux (dan mungkin juga unit lainnya)?
Bagaimana cara mendaftar semua anggota grup di Linux (dan mungkin juga unit lainnya)?
Jawaban:
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 id
untuk 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 passwd
akan 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";
}
}
getent passwd
mungkin tidak berfungsi (jika misalnya Anda menggunakan sssd).
getent passwd
saya akan menganggapnya sebagai bug di sssd.
Gunakan Python untuk mendaftar anggota grup:
python -c "import grp; cetak grp.getgrnam ('GROUP_NAME') [3]"
lid -g groupname | cut -f1 -d'('
Perintah berikut akan mencantumkan semua pengguna milik <your_group_name>
, tetapi hanya mereka yang dikelola oleh /etc/group
basis 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
Perintah berikut akan mencantumkan semua pengguna milik <your_group_name>
, tetapi hanya mereka yang dikelola oleh /etc/group
basis 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
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 passwd
dan 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 true
untuk keluar dengan 0
status seperti yang disarankan oleh @Max Chernyak alias hakunin ; dibuang stderr
untuk melewati mereka yang sesekali groups: cannot find name for group ID xxxxxx
.
; true
. Mengembalikan 0 adalah baik untuk menghindari tersandungnya sistem manajemen konfigurasi Anda (Chef, Ansible, dll).
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'
grep
akan cocok dengan pengguna yang namanya berisi nomor grup (mis. sc0tt
Akan ditampilkan sebagai bagian dari root
grup). 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.)
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.
id -Gn
ke/usr/xpg4/bin/id -G -n
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";
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.
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')")
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
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. :-)
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.
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.
getent group groupname | awk -F: '{print $4}' | tr , '\n'
Ini memiliki 3 bagian:
1 - getent group groupname
menunjukkan baris grup dalam file "/ etc / group". Alternatif untuk cat /etc/group | grep groupname
.
2 - awk
cetak hanya anggota dalam satu baris yang dipisahkan dengan ','.
3 - tr
ganti ',' dengan baris baru dan cetak setiap pengguna secara berurutan.
4 - Opsional: Anda juga dapat menggunakan pipa lain dengan sort
, jika pengguna terlalu banyak.
Salam
Saya pikir cara termudah adalah langkah-langkah berikut, Anda tidak perlu menginstal paket atau perangkat lunak apa pun:
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)
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.
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]])"
Saya sudah mencoba grep 'sample-group-name' /etc/group
, yang akan mencantumkan semua anggota grup yang Anda tentukan berdasarkan contoh di sini
/etc/group
sudah 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.