5

I want to compare each user in the passwd file with his entry in the shadow file, and print out the whole line of the passwd file if the entry in the shadow file matches 999999. What is the easiest way in Perl to do this? Or I suppose I could awk the values out of one file and match in the other file? What is the best way of doing this?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
paul44
  • 149
  • 3
  • @Svante: correct on the extraneous apostrophe, but I'd argue that "its" is correct: "compare each user [entry] in the passwd file with *its* [corresponding] entry in the shadow file. – Dennis Williamson Feb 24 '10 at 14:52

4 Answers4

3
awk -F":" 'FNR==NR&&$5=="99999"{user[$1];next}($1 in user)' /etc/shadow /etc/passwd

change FNR==NR&&$5=="99999" to FNR==NR&&$5=="99999"&&$2!="!!" if you want to exclude lines with "!!"

ghostdog74
  • 327,991
  • 56
  • 259
  • 343
2
#! /usr/bin/perl

use warnings;
use strict;

sub read_passwd {
  open my $fh, "<", "/etc/passwd" or die "$0: open: $!";

  my %passwd;
  while (<$fh>) {
    next unless /^([^:]+)/;
    $passwd{$1} = $_;
  }

  \%passwd;
}

my $passwd = read_passwd;

open my $fh, "<", "/etc/shadow" or die "$0: open: $!";
while (<$fh>) {
  my($user,$maxage) = (split /:/)[0,4];
  next unless $maxage eq 99999;
  if ($passwd->{$user}) {
    print $passwd->{$user};
  }
  else {
    warn "$0: no passwd entry for '$user'";
  }
}
Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
0
sudo perl -F: -lane '(1..eof)?($_{$F[0]}=$_):/999999/&&($_=$_{$F[0]})&&print' /etc/passwd /etc/shadow
codeholic
  • 5,680
  • 3
  • 23
  • 43
0

You could use AnyData::Format::Password:

#!/usr/bin/perl

use strict; use warnings;
use AnyData;

my $passwd = adTie(Passwd => 'passwd' );
my $shadow = adTie(Passwd => 'shadow' );

for my $user (keys %$shadow) {
    if ( $user->{fullname} and $user->{fullname} eq '999999' ) {
         print $passwd->{$user->{username}}{fullname}, "\n";
    }
}

Output:

...
Privilege-separated SSH
RPC Service User
Anonymous NFS User
HAL daemon

Or:

for my $user (keys %$shadow) {
    if ( $user->{fullname} and $user->{fullname} eq '999999' ) {
        my @values = map { defined $_ ? $_ : '' }
            @{ $passwd->{$user->{username}} }{@fields};
        print join(':', @values), "\n";
    }
}
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339