On Thu, Dec 21, 2006 at 01:25:01PM -0700, Tom Smith wrote: > Chad Perrin wrote: > > > >That's why I said you may as well either just use the id utility from > >the shell if you're not going to grab group memberships in an > >idiomatically Perlish way -- the Perl code is likely to be more > >portable. Of course, specifying the path to the group file, as I > >originally suggested, might not be the most portable way to do that (in > >retrospect). > > > > That's interesting... But I couldn't determine another (perhaps better) > way of doing it. > > I tried the getgr* and getpw* functions, but they were too > specific--that is, one has to specify which user or group they want > information about. And the user information won't tell me such things as > which groups the user belongs to... And I can't get information about a > group unless I know the group name ahead of time... And so on. This is > why I decided on the method I did. (Perhaps I wasn't doing something > correctly with those functions?)
Actually, using getgrent and getpwent is probably the way to go, unless there's a module that makes this easier. Something I just threw together (caution -- I have not tested it much) that seems to do the trick is: #!/usr/local/bin/perl -l use strict; use warnings; my $user = $ARGV[0]; my @gr_list; my @pw_info; while (@pw_info = getpwent) { if ($pw_info[0] eq $user) { my @gr_info; while (@gr_info = getgrent) { push(@gr_list, $gr_info[0]) if ($gr_info[3] =~ /\b$user\b/); push(@gr_list, $gr_info[0]) if ($gr_info[2] eq $pw_info[3]); } } } print foreach @gr_list; In the above, I'm using the first if statement to ensure that each result from both getpwent() and getgrent() will only be included once, because there's only one line in /etc/passwd that'll match ($pw_info[0] eq $user). The reason I have the first push statement where it is, composed the way it is, should be obvious: I'm pushing all getgrent() results for the group name where its member list includes $user onto the @gr_list array. The second push statement is there, and necessarily composed the way it is, because getpwent() only gives you the gid, and if you're looking for the group name you need to match the gid from getpwent() with the gid from getgrent() to figure out the group name. The print statement is there for testing the ouptut of my complex little control structure, and it uses a foreach because, coupled with the -l option in the shebang line, it prints out each array element on its own line in STDOUT. I'm sure that could be made prettier by someone with better Perl mojo than I have at the moment, and it could be made a bit simpler if all you want is the gid for each group rather than the group name. > > In either case, the interesting point about your comment is that every > *nix system I've ever touched (Linux (includes Redhat, Debian, Ubuntu, > Mandrake, and Gentoo), FreeBSD, Solaris, and AIX) have all had their > group file located at /etc/group. Do you have a specific example or > reason of why someone might want to change this location? No, I don't. I'm just sometimes paranoid about such things when writing code for portability. -- CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ] "The first rule of magic is simple. Don't waste your time waving your hands and hopping when a rock or a club will do." - McCloctnick the Lucid -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>