tbo has asked for the wisdom of the Perl Monks concerning the following question:

I want to get the secondary groups of a user name $name for linux. I try that :

while (1) { last unless (($gname,$gpasswd,$gid,$members)=getgrent ()); @list_members=split (/\s+/,$members); @list=grep (/$name/,@list_members); if ($list[0] eq $name) { push (@sec_gp,"$gname"); }

But I've got 2 problems :
- the groups are pushed twice in @sec_gp,
- I 'm not sure it's the better way to do it.
Thanks.

Replies are listed 'Best First'.
Re: To get the secondary groups for linux
by jlongino (Parson) on Jan 05, 2002 at 05:18 UTC
    This version eliminates the unless statement, but is basically the same as your example (you should use strict). I'm running this on a Solaris 8.0 system but I don't get any duplicates.
    use strict; my @sec_gp; my $name = "xxxxx"; while (my ($gname,$gpasswd,$gid,$members)=getgrent) { my @list_members=split (/\s+/,$members); my @list=grep (/$name/,@list_members); if ($list[0] eq $name) { push (@sec_gp,"$gname"); } } print "\@sec_gp: "; print "$_\n" foreach @sec_gp;
    Output:
    @sec_gp: acad libsoftwrite helpdesk codes

    --Jim Update: The above was hastily done. Better is the following (still room for improvement I'm sure):

    push(@sec_gp, "$gname") if $list[0] eq $name;
    for the original if statement.
      I have understand why I have duplicatas : a NIS server is running. So, now I know that the function getgrent looks both /etc/passwd and the NIS database. It doesn't appear in the french man page of getgrent (Mandrake). PS : I've got to learn english before learning Perl !
Re: To get the secondary groups for linux
by kschwab (Vicar) on Jan 05, 2002 at 08:37 UTC
    On the off chance that you are more interested in the current group membership of the current running process, there's POSIX::getgroups.
    use POSIX qw(getgroups); # get list of the current groups for this process my @gidlist=getgroups(); # you'd have to translate numeric gid's to # the names here
    Update:

    Here's another shot at getting secondary groups, this one from the id command in the Perl Power Tools project:

    while ( my($name,$pw,$gid,$members) = getgrent ) { push(@rgids,$gid) if ( grep($_ eq $user,split(/\s+/,$members)) ); }
Re: To get the secondary groups for linux
by belg4mit (Prior) on Jan 05, 2002 at 13:28 UTC
    Yeah, I did this in a cron; in perl. My solution was (roughly, this is cut & paste with edit on the fly):
    while( my @F = getgrent() ){ push @groups, [@F] }; endgrent(); @sec_gp = map($_->[2], grep($_->[3] =~ /\b$name\b/,@groups) ) );

    --
    perl -pe "s/\b;([st])/'\1/mg"