Linuxグループのすべてのユーザーをリストする方法は?


273

Linux(および場合によっては他のunice)でグループのすべてのメンバーをリストするにはどうすればよいですか?


1
@ Silmari89、プログラムでそれを実行したい場合はそうではありません。
ポールトンブリン

2
私はここに新しいのですが、質問を投稿した直後にSFが存在することがわかりました。SFかSOのどちらかに属していることに同意します。
user323094

5
もちろん、今ではプログラムによる解決策があるので、ここでも正当化できます。
ゼッド

回答:


103

残念ながら、私が知っている、これを実行するための優れたポータブルな方法はありません。/ etc / groupを解析しようとすると、他の人が示唆しているように、そのグループをプライマリグループとして持つユーザーや、UNIXフラットファイル以外のメカニズム(LDAP、NIS、 pam-pgsqlなど)。

私が絶対に自分でこれを行う必要がある場合は、おそらく逆に行います:idシステム上のすべてのユーザーのグループを取得するために使用し(これにより、すべてのソースがNSSに表示されます)、ハッシュを維持するためにPerlまたは同様のものを使用します発見された各グループのテーブルは、そのユーザーのメンバーシップを記録しています。

編集:もちろん、同様の問題が残ります。システム上のすべてのユーザーのリストを取得する方法です。私の場所はフラットファイルとLDAPのみを使用しているため、両方の場所からリストを取得できますが、環境によってはそうでない場合もあります。

編集2:getent passwdLDAP / 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";
    }
}

3
答えてくれたすべての人に感謝します。それを行うためのポータブルな方法を探していました。簡単で移植可能な方法がないというあなたの情報は役に立ちました。また、問題をより深く理解するのに役立つ状況について最も詳しく説明していただき、ありがとうございます。あなたの回答を受け入れられたものとして選びました。
user323094

2
スクリプトをLinux Foundationに寄付することは可能でしょうか?それは2012年であり、グループのメンバーを取得する簡単な方法はまだありません。それがLinuxについて私を苛立たせている。
winteck 2012

6
ISCのようなライセンスを追加しました。これは、ほぼすべてのグループと互換性があるはずです。受け入れられると思われる場所に自由に提出してください。
Zed

PAMはアカウント情報を提供しません。それを行うのがネームサービススイッチ(nsswitch)です。すべての「データベース」(データプロバイダー)が列挙をサポートgetent passwdするわけではないため、機能しない場合があります(たとえば、sssdを使用している場合)。

PAMとNSSの有効点-参照を変更しました。私はそれを使用していませんが、sssdは一見すると適切なデータプロバイダーというよりはnscdの置き換えのようgetent passwdに見えます。壊れた場合は、sssdのバグと見なします。
Zed

239
getent group <groupname>;

LinuxとSolarisの両方で移植可能であり、ローカルグループ/パスワードファイル、NIS、およびLDAP構成で動作します。


43
そのグループをデフォルトグループとして持っているユーザーは表示しません。
rlpowell 2013年


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

7
これは、ふたが標準のDebianインストールにないことを除いて、最も良い方法です。Ubuntuでは、libuserオプションパッケージにあります(同じ名前のid-utilsのパッケージではありません)。Debianでは見つかりませんでした:(
user323094 '

Scientific Linuxで私のために働いた
blong

DebianのWheezyにに、蓋があまりにもlibuserパッケージにある
リュイス

2
@JohnMcGehee RHELはAustereLinuxと呼ばれるべきでした
goelakash

1
「-g」は私にはオプションではありません。Ubuntu 16.04にid-utilsバージョン4.6がインストールされています。
Wilson Biggs 2017

25

次のコマンドは<your_group_name>、に属するすべてのユーザーを一覧表示し/etc/groupますが、LDAP、NISなどではなく、データベースによって管理されているユーザーのみを一覧表示します。また、セカンダリグループに対してのみ機能し、プライマリグループがプライマリであるため、そのグループをプライマリとして設定しているユーザーは一覧表示しませんGIDファイルに(数値グループID)として保存されます/etc/passwd

grep <your_group_name> /etc/group

4
grep <username> / etc / groupのように、そのファイルに直接grepできます。より速く、より少ないオーバーヘッド。
ペイントボックス2014

16

次のコマンドは<your_group_name>、に属するすべてのユーザーを一覧表示し/etc/groupますが、LDAP、NISなどではなく、データベースによって管理されているユーザーのみを一覧表示します。また、セカンダリグループに対してのみ機能し、プライマリグループがプライマリであるため、そのグループをプライマリとして設定しているユーザーは一覧表示しませんGIDファイルに(数値グループID)として保存されます/etc/passwd

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

7
そのグループをデフォルトグループとして持っているユーザーは表示しません。
rlpowell 2013年

3
NISとLDAPをチェックしません。
パヴェルNadolski

12

次のシェルスクリプトは、すべてのユーザーを反復処理し、特定のグループに属するユーザー名のみを出力します。

#!/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でユーザーとグループ(passwdgroupファイルだけでなく)をチェックします。また、グループに追加されていないが、グループがプライマリグループとして設定されているユーザーも考慮されます。

編集:ユーザーが同じ名前のグループに属していないまれなシナリオの修正が追加されました。

編集:シェルスクリプトの形式で記述。@Max Chernyak aka hakuninによって提案されたステータスでtrue終了するために追加されました。それらを時折スキップするために破棄されました。0stderrgroups: cannot find name for group ID xxxxxx


これは素晴らしく、非常に簡潔ですが、グループ名とユーザー名を出力します
andrew lorien

@andrewlorien、あなたが言及した問題を修正したいと思います。そうでない場合は、詳細をお知らせください。
パヴェルNadolski

このスニペットは良いですが、終了コード1を返しますが、0を返さない理由はありますか?おそらく簡単に修正できますか?
Max Chernyak 14

@hakunin、最後のユーザー名がグループに属していない場合、0を返しません。endステートメントに "|| true"を追加して、これが必要な場合は常に0を取得できます。次に、出力をチェックして、ユーザーが見つかったかどうかを確認できます。
パヴェルNadolski

@PawełNadolski気づいたので、追加してしまいました; true。0を返すことは、構成管理システム(Chef、Ansibleなど)の作動を回避するのに適しています。
Max Chernyak 2014

7

単一のコマンドラインでそれを行うことができます:

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

上記のコマンドは、グループ名をプライマリグループとして持つすべてのユーザーを一覧表示します

あなたも持つユーザ一覧表示したい場合はグループ名自分のセカンダリ・グループとしては、次のコマンドを使用します。

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

1
警告:grep名前にグループ番号が含まれているユーザーに一致します(たとえばsc0ttrootグループの一部として表示されます)。これが問題である場合は、正規表現を使用します:$(getent group <groupname> | cut -d: -f3)\$(セミコロン、グループID、および行の終わりに一致します)。(正規表現に引用符を追加したり、不平を言ったりしないでください。)
Scott Stevens

@ScottS正当な落とし穴。提案された手順を推奨します
Bhavik

3

少しgrepとtr:

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

4
そのグループをデフォルトグループとして持っているユーザーは表示しません。
rlpowell 2013年

3

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";
    }
}

この提案を共有するより良い方法がある場合は、お知らせください。私はいろいろな方法を考えましたが、これが私が思いついたものです。


確認した変更後のSolaris 10上で作業id -Gn/usr/xpg4/bin/id -G -n
user667489

3

上記の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";

リンクのみの回答は、スタックオーバーフローでは適切な回答とは見なされません。これは質問への回答を提供しないか、この回答が承認された回答よりも優れているかについて詳しく説明しないため、これを削除することを検討してください。または、十分な評判を得たら、これをコメントとして追加できます。自分の投稿にはいつでもコメントできます。
Dipen Shah 2015

2

この機能を提供する「members」と呼ばれる便利なDebianおよびUbuntuパッケージがあります。

説明:グループのメンバーを表示します。デフォルトでは、すべてのメンバーメンバーはグループの補足です。グループは指定されたユーザーが属するグループを示し、メンバーは指定されたグループに属するユーザーを示します。

...プライマリメンバー、セカンダリメンバーの両方を1行に、それぞれ別の行に要求できます。


opがopenwrtを使用している場合はどうなりますか?
user2284570

確かに便利ですが、残念ながらドメイングループメンバーを報告しません。
simlev

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')")

0

/ 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

0

UNIX(GNU / Linuxとは対照的)には、listusersコマンドがあります。listusersについては、Solarisのマニュアルページを参照してください

このコマンドは、オープンソースの家宝プロジェクトの一部であることに注意してください。RMSはグループと権限を信じていないため、GNU / Linuxにはないものと思います。:-)


1
このリンクで質問に答えることができますが、回答の重要な部分をここに含め、参照用のリンクを提供することをお勧めします。リンクされたページが変更されると、リンクのみの回答が無効になる可能性があります。- レビューから
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 ProjectのWebサイトから:Heirloom Projectは、標準的なUnixユーティリティの従来の実装を提供しています。多くの場合、それらはCalderaとSunによってオープンソースとしてリリースされたオリジナルのUnix資料から派生したものです。インターフェースは従来の慣例に従います。それらは一般的にSystem Vと互換性がありますが、時間の経過とともに一般的に使用されるようになった拡張機能が提供されることもあります。ほとんどのユーティリティは、POSIX準拠を目的としたバリアントにも含まれています。
Alun Carr

0

他の回答にリストされているすべての一般的な落とし穴を考慮に入れる非常に単純な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を使用して何でも実行します。


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

これには3つの部分があります。

1- getent group groupname「/ etc / group」ファイル内のグループの行を示します。の代替cat /etc/group | grep groupname

2- awkprintは、「、」で区切られた1行のメンバーのみです。

3- tr「、」を新しい行に置き換え、各ユーザーを続けて印刷します。

4-オプション:sortユーザーが多すぎる場合は、で別のパイプを使用することもできます。

よろしく


0

次の手順が最も簡単な方法だと思います。パッケージやソフトウェアをインストールする必要はありません。

  1. 最初に、ユーザーを知りたいグループのGIDを見つけます。そのための方法はたくさんあります 。cat / etc / group (最後の列はGIDです) id user (ユーザーは所属する誰かです)グループ)

  2. ここで、/ 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列の)グループのみをフィルターします選択していました。


0

これは、ユーザーのデフォルトグループメンバーシップ(から/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]])"

-1

私が試したところgrep 'sample-group-name' /etc/groupここの例に基づいて指定したグループのすべてのメンバーがリストされます


1
Grepping /etc/groupはすでに少なくとも3つの他の回答にありますが、あなたの回答はそれらにどのような価値をもたらしますか?また、これらすべての他の回答にはコメントを持っている第二のグループのようなソリューションの作品のみともないなどのLDAP、NISで管理アカウントのない仕事
デヴィッドFerenczyRogožan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.