1. ホーム
  2. linux

[解決済み】Linuxのグループ内の全ユーザーをリストアップする方法は?

2022-04-01 21:33:08

質問

Linuxで、あるグループのメンバー全員をリストアップするにはどうしたらよいですか(他のユニックスの場合もあります)?

どのように解決するのですか?

残念ながら、私が知っている限りでは、これを行うための良い、ポータブルな方法はありません。 他の人が提案しているように /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 ([email protected] or [email protected])
#
# 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";
    }
}