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