我在循环(和& foreach)和AoH背后遇到了逻辑。我有关于循环和哈希数组的基本知识,但我不太清楚如何将它们组合成一个简单的解决方案。我的任务是检查普通用户的密码年龄,如果它早于 n -days(最后一部分对我来说没关系,我知道如何解决它,使用GetOptions等)。 。
为了实现这一目标,我找到了一个解决方案:
1 将文件 / etc / passwd 加载到脚本中,执行正则表达式搜索以查找常规用户。 Linux系统中的普通用户拥有1000及以上的ID,因此我使用此正则表达式来查找这些:
/(\w+)[:]x[:]1[0-9]{3}/
2 将正则表达式serch的结果加载到数组中:
my (@Usernames, %pwdsettings);
while (my $pwdsettings = <$fh2>) {
if ($pwdsettings =~ /(\w+)[:]x[:]1[0-9]{3}/) {
$pwdsettings{"Username"} = $1;
push (@Usernames, \%pwdsettings);
}
}
3 Preform chage 检查数组中的每个条目:
my $pwdsett_dump = "tmp/pwdsett-dump.txt";
...
foreach (@Usernames) {
system("chage -l $_ > $pwdsett_dump")
}
4 打开$pwdsett_dump
,然后执行第二次正则表达式搜索,以获取上次更改密码的日期。之后,将结果加载到数组(AoH)中的现有哈希:
open (my $fh3, "<", $pwdsett_dump) or die "Could not open file '$pwdsett_dump': $!";
while (my $array = <$fh3>) {
if ($array =~ /^Last\s+password\s+change\s+:\s(\w{3})\s+(\d{2}),\s+(\d{4})/) {
$pwdsettings{"Month"} = $1;
$pwdsettings{"Day"} = $2;
$pwdsettings{"Year"} = $3;
}
}
但是,某个地方出现了严重错误。我的脚本只加载1个用户到AoH,第二个用户从未加载,我得到$VAR1->[0]
。
我想要的是了解如何以正确的方式创建AoH和循环。
完整脚本:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $pwdsett_dump = "tmp/pwdsett-dump.txt";
my $usernames_dump = "tmp/usernames-dump.txt";
system("cat /etc/passwd > $usernames_dump");
open (my $fh2, "<", $usernames_dump) or die "Could not open file '$usernames_dump': $!";
my (@Usernames, %pwdsettings);
while (my $pwdsettings = <$fh2>) {
if ($pwdsettings =~ /(\w+)[:]x[:]1[0-9]{3}/) {
$pwdsettings{"Username"} = $1;
push (@Usernames, \%pwdsettings);
}
}
foreach (@Usernames) {
system("chage -l $_ > $pwdsett_dump")
}
open (my $fh3, "<", $pwdsett_dump) or die "Could not open file '$pwdsett_dump': $!";
while (my $array = <$fh3>) {
if ($array =~ /^Last\s+password\s+change\s+:\s(\w{3})\s+(\d{2}),\s+(\d{4})/) {
$pwdsettings{"Month"} = $1;
$pwdsettings{"Day"} = $2;
$pwdsettings{"Year"} = $3;
}
}
print Dumper \@Usernames;
答案 0 :(得分:0)
输出含义时需要附加文件“&gt;&gt;”而不是“&gt;”这将覆盖该文件。
system("chage -l $_ >> $pwdsett_dump")
当你在循环中运行它时,每次循环执行时都会覆盖它。
使用:
foreach (@Usernames) {
system("chage -l $_ >> $pwdsett_dump")
}
########sample script
#!/usr/bin/perl
use strict;
use warnings;
my $usernames_dump = "/etc/passwd";
open (my $fh2, "<", $usernames_dump) or die "Could not open file '$usernames_dump': $!";
my @pwdsettings;
my $i =0;
my @pwdsett_dump;
while (<$fh2>) {
if ($_ =~ /(\w+)[:]x[:]1[0-9]{3}/) {
my @user = split(/:/, $_);
$pwdsettings[$i] = $user[0];
$pwdsett_dump[$i] = `chage -l $user[0]|grep Last`;
$pwdsett_dump[$i] =~ s/Last.*://;
$pwdsett_dump[$i] =~ s/,//;
my @m = split(/ /,$pwdsett_dump[$i]);
print "$user[0]\t Date: $m[2] Month: $m[1] Year: $m[3]\n";
$i++;
}
}
Output: testuser Date: 12 Month: May Year: 2015