Linux(および場合によっては他のunice)でグループのすべてのメンバーをリストするにはどうすればよいですか?
Linux(および場合によっては他のunice)でグループのすべてのメンバーをリストするにはどうすればよいですか?
回答:
残念ながら、私が知っている、これを実行するための優れたポータブルな方法はありません。/ etc / groupを解析しようとすると、他の人が示唆しているように、そのグループをプライマリグループとして持つユーザーや、UNIXフラットファイル以外のメカニズム(LDAP、NIS、 pam-pgsqlなど)。
私が絶対に自分でこれを行う必要がある場合は、おそらく逆に行います:id
システム上のすべてのユーザーのグループを取得するために使用し(これにより、すべてのソースがNSSに表示されます)、ハッシュを維持するためにPerlまたは同様のものを使用します発見された各グループのテーブルは、そのユーザーのメンバーシップを記録しています。
編集:もちろん、同様の問題が残ります。システム上のすべてのユーザーのリストを取得する方法です。私の場所はフラットファイルとLDAPのみを使用しているため、両方の場所からリストを取得できますが、環境によってはそうでない場合もあります。
編集2:getent passwd
LDAP / NISなどからのユーザーを含むシステム上のすべてのユーザーのリストを返すが、 getent group
それでもデフォルトのグループエントリを介してのみメンバーであるユーザーを見逃すことになると、誰かが思い出させたので、この簡単なハックを書いてください。
#!/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
するわけではないため、機能しない場合があります(たとえば、sssdを使用している場合)。
getent passwd
に見えます。壊れた場合は、sssdのバグと見なします。
getent group <groupname>;
LinuxとSolarisの両方で移植可能であり、ローカルグループ/パスワードファイル、NIS、およびLDAP構成で動作します。
Pythonを使用してグループメンバーを一覧表示します。
python -c "インポートgrp;印刷grp.getgrnam( 'GROUP_NAME')[3]"
lid -g groupname | cut -f1 -d'('
次のコマンドは<your_group_name>
、に属するすべてのユーザーを一覧表示し/etc/group
ますが、LDAP、NISなどではなく、データベースによって管理されているユーザーのみを一覧表示します。また、セカンダリグループに対してのみ機能し、プライマリグループがプライマリであるため、そのグループをプライマリとして設定しているユーザーは一覧表示しませんGID
ファイルに(数値グループID)として保存されます/etc/passwd
。
grep <your_group_name> /etc/group
次のコマンドは<your_group_name>
、に属するすべてのユーザーを一覧表示し/etc/group
ますが、LDAP、NISなどではなく、データベースによって管理されているユーザーのみを一覧表示します。また、セカンダリグループに対してのみ機能し、プライマリグループがプライマリであるため、そのグループをプライマリとして設定しているユーザーは一覧表示しませんGID
ファイルに(数値グループID)として保存されます/etc/passwd
。
awk -F: '/^groupname/ {print $4;}' /etc/group
次のシェルスクリプトは、すべてのユーザーを反復処理し、特定のグループに属するユーザー名のみを出力します。
#!/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
使用例:
./script 'DOMAIN+Group Name'
注:このソリューションでは、NISとLDAPでユーザーとグループ(passwd
とgroup
ファイルだけでなく)をチェックします。また、グループに追加されていないが、グループがプライマリグループとして設定されているユーザーも考慮されます。
編集:ユーザーが同じ名前のグループに属していないまれなシナリオの修正が追加されました。
編集:シェルスクリプトの形式で記述。@Max Chernyak aka hakuninによって提案されたステータスでtrue
終了するために追加されました。それらを時折スキップするために破棄されました。0
stderr
groups: cannot find name for group ID xxxxxx
; true
。0を返すことは、構成管理システム(Chef、Ansibleなど)の作動を回避するのに適しています。
単一のコマンドラインでそれを行うことができます:
cut -d: -f1,4 /etc/passwd | grep $(getent group <groupname> | cut -d: -f3) | cut -d: -f1
上記のコマンドは、グループ名をプライマリグループとして持つすべてのユーザーを一覧表示します
あなたも持つユーザ一覧表示したい場合はグループ名自分のセカンダリ・グループとしては、次のコマンドを使用します。
getent group <groupname> | cut -d: -f4 | tr ',' '\n'
grep
名前にグループ番号が含まれているユーザーに一致します(たとえばsc0tt
、root
グループの一部として表示されます)。これが問題である場合は、正規表現を使用します:$(getent group <groupname> | cut -d: -f3)\$
(セミコロン、グループID、および行の終わりに一致します)。(正規表現に引用符を追加したり、不平を言ったりしないでください。)
少しgrepとtr:
$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3
Zedの実装は、おそらく他の主要なUNIXの一部で動作するように拡張する必要があります。
誰かがSolarisまたはHP-UXハードウェアにアクセスできますか?; それらのケースをテストしませんでした。
#!/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";
}
}
この提案を共有するより良い方法がある場合は、お知らせください。私はいろいろな方法を考えましたが、これが私が思いついたものです。
id -Gn
に/usr/xpg4/bin/id -G -n
上記のperlコードと同様にこれを行いましたが、getentとidをネイティブのperl関数に置き換えました。これははるかに高速で、異なる* 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";
この機能を提供する「members」と呼ばれる便利なDebianおよびUbuntuパッケージがあります。
説明:グループのメンバーを表示します。デフォルトでは、すべてのメンバーメンバーはグループの補足です。グループは指定されたユーザーが属するグループを示し、メンバーは指定されたグループに属するユーザーを示します。
...プライマリメンバー、セカンダリメンバーの両方を1行に、それぞれ別の行に要求できます。
getent group insert_group_name_here | awk -F ':' '{print $4}' | sed 's|,| |g'
これにより、スペースで区切られたユーザーのリストが返されます。これは、配列を設定するためにスクリプトで使用したものです。
for i in $(getent group ftp | awk -F ':' '{print $4}' | sed 's|,| |g')
do
userarray+=("$i")
done
または
userarray+=("$(getent group GROUPNAME | awk -F ':' '{print $4}' | sed 's|,| |g')")
/ etc / passwdおよび/ etc / groupからユーザーのリストを返すスクリプトは次のとおりです。NISやLDAPはチェックされませんが、デフォルトグループとしてグループを持っているユーザーが表示されます。Debian4.7と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
またはワンライナーとして、ここから直接カットアンドペーストできます(最初の変数のグループ名を変更します)
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
UNIX(GNU / Linuxとは対照的)には、listusersコマンドがあります。listusersについては、Solarisのマニュアルページを参照してください。
このコマンドは、オープンソースの家宝プロジェクトの一部であることに注意してください。RMSはグループと権限を信じていないため、GNU / Linuxにはないものと思います。:-)
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.
他の回答にリストされているすべての一般的な落とし穴を考慮に入れる非常に単純なawkスクリプトを次に示します。
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}'
私はこれをLDAP対応のセットアップで使用しており、solaris 8+やhpuxを含む、標準に準拠したgetent&awkを使用して何でも実行します。
次の手順が最も簡単な方法だと思います。パッケージやソフトウェアをインストールする必要はありません。
最初に、ユーザーを知りたいグループのGIDを見つけます。そのための方法はたくさんあります 。cat / etc / group (最後の列はGIDです) id user (ユーザーは所属する誰かです)グループ)
ここで、/ etc / passwdファイルのすべてのユーザーをリストしますが、次の一連のコマンドを使用していくつかのフィルターを適用し、前のグループのメンバーのみを取得します。
cut -d:-f1,4 / etc / passwd | grep GID (GIDはステップ1で取得した番号です)
cutコマンドは、ファイルの一部の「列」のみを選択します。この場合、パラメーターdは区切り文字「:」を設定します。パラメーター-fは、「フィールド」(または列)を選択して、アウトケース(オン)で1および4を表示します。ファイル/etc/passwd。1º列はユーザーの名前、4ºはユーザーが属するグループのGIDです)、grepを確定するには、GIDは(4 you列の)グループのみをフィルターします選択していました。
これは、ユーザーのデフォルトグループメンバーシップ(から/etc/passwd
)とグループデータベース(/etc/group
)を考慮した別のPythonワンライナーです
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]])"
/etc/group
はすでに少なくとも3つの他の回答にありますが、あなたの回答はそれらにどのような価値をもたらしますか?また、これらすべての他の回答にはコメントを持っている第二のグループのようなソリューションの作品のみともないなどのLDAP、NISで管理アカウントのない仕事