frech@mwraaa.army.mil (Norman R. Frech CPLS) (11/21/90)
I am having problems with the following code. What I am trying to do is slurp the password file fields $login,$home into a varible, run who, and then grep the $home out of my variable for each person logged on. I figured it would be faster to grab the password file one time in the beginning instead of opening it for each person out of the who. I have tried various search approaches and they either return a 1 or something completely erroneous. It is evident I do not have a clue. Help. *** cut here *** eval "exec /usr/local/bin/perl -S $0 $*" if $running_under_some_shell; # this emulates #! processing on NIH machines. # (remove #! line above if indigestible) open(HOME, "/etc/passwd") || die "Can't access passwork file: $!\n"; while (<HOME>) { ($login,$passwd,$uid,$gid,$gcos,$home,$shell) = split(/:/); $pass .= "$login:$home\n"; } close HOME; print $pass; print "\n"; # open an input pipe to run who open(WHO, "who |") || die "Can't run who: $!\n"; ($wday, $mo, $today) = split(' ', `date`); while (<WHO>) { chop; ($user, $tty, $month, $mday, $time) = split; print $user; print "\n"; # grab the home directory from $pass @foo = grep($pass,$user); print @foo; print "\n"; }
tchrist@convex.COM (Tom Christiansen) (11/22/90)
In article <1990Nov20.164319.7326@uvaarpa.Virginia.EDU> frech@mwraaa.army.mil writes: |I am having problems with the following code. What I am trying to do |is slurp the password file fields $login,$home into a varible, |run who, and then grep the $home out of my variable for each person |logged on. I figured it would be faster to grab the password file |one time in the beginning instead of opening it for each person |out of the who. I have tried various search approaches and they |either return a 1 or something completely erroneous. It is evident |I do not have a clue. Help. | |*** cut here *** | |eval "exec /usr/local/bin/perl -S $0 $*" | if $running_under_some_shell; | # this emulates #! processing on NIH machines. | # (remove #! line above if indigestible) | |open(HOME, "/etc/passwd") || die "Can't access passwork file: $!\n"; | |while (<HOME>) { |($login,$passwd,$uid,$gid,$gcos,$home,$shell) = split(/:/); |$pass .= "$login:$home\n"; |} |close HOME; |print $pass; |print "\n"; |# open an input pipe to run who | |open(WHO, "who |") || die "Can't run who: $!\n"; | |($wday, $mo, $today) = split(' ', `date`); | |while (<WHO>) { | chop; | ($user, $tty, $month, $mday, $time) = split; | print $user; | print "\n"; |# grab the home directory from $pass | @foo = grep($pass,$user); | print @foo; | print "\n"; | |} This is another case where you would like to use an associative array. Hashded arrays and regular expressions are your two greatest friends in perl. I think I would write that more code more like this: open(WHO, "who |"); # this isn't going to fail while (<WHO>) { ($user) = /^(\w+)\b/; print $user, ' ', &home($user), "\n"; } ##> BUG WORK-AROUND HERE: CLOSE STILL DOESN'T FAIL iff $? close(WHO); die "can't run who command: $!" if $?; sub home { local($who); $who = $_[0] || $ENV{'USER'} || getlogin || (getpwuid($<))[0] || die "Intruder alert, bailing out"; unless(defined $Homes{$who}) { $Homes{$who} = (getpwnam($who))[7] || '/'; } $Homes{$who}; } I don't know why if a open "bogus|" fails to get something, the close doesn't fail. "close foo || die" doesn't do it. --tom