【发布时间】:2010-02-25 06:31:23
【问题描述】:
我想扫描 passwd 文件并仅在用户未锁定时打印行。也就是说,passwd -S $user 不会返回“密码:锁定”。我可以在 ksh 中轻松完成。在 Perl 中执行此操作的最佳方法是什么?
【问题讨论】:
标签: perl
我想扫描 passwd 文件并仅在用户未锁定时打印行。也就是说,passwd -S $user 不会返回“密码:锁定”。我可以在 ksh 中轻松完成。在 Perl 中执行此操作的最佳方法是什么?
【问题讨论】:
标签: perl
与单线相同。
sudo perl -F: -lane 'print $F[0] if $F[1]!~/^!/' /etc/shadow
【讨论】:
以前,此答案报告了如何仅打印锁定的用户。错误已更正。
在 Linux 上,锁定的用户帐户的密码以 '!' 开头。您可以自己解析以冒号分隔的/etc/shadow 文件:
# Run as root with /etc/shadow as program argument
while (<>) {
chomp;
my ($user, $password, $remainder) = split /:/, $_, 3;
print $user."\n" unless $password =~ /^!/;
}
编辑:另一种可移植的方法是使用getpwent 函数:
# Must run as root
while (my ($user, $password) = getpwent) {
print $user."\n" unless $password =~ /^!/;
}
注意:您需要root用户才能从/etc/shadow读取用户密码并查看用户是否被锁定。
【讨论】:
我不确定您是否正在寻找一种命令行方式来执行此操作,以下代码假定 passwd -S 的输出完全您指定它的方式(这在实践中可能行不通),但这是一种方法:
cat /etc/passwd | perl -ne '$user = (split /:/)[0]; print "$user\n" if `passwd -S $user` ne "Password: locked"'
在实践中,最后你可能需要某种毛茸茸的正则表达式,例如:
`passwd -S $user` !~ /^\s*Password\s*:\s*locked\s*$/im'
末尾的“i”使其不区分大小写(这可能不是必需的),而“m”允许匹配多行输出 [来自 passwd -S]。如果没有看到您匹配的确切输出(在您的 *nix 上),很难准确地说出您需要什么。
例如,在 cygwin 上,我认为等价的应该是这样的:
`passwd -S $user` !~ /^\s*Account\s+disabled\s+:\s+yes\s*$/im'
【讨论】:
open(F,"<","/etc/shadow") or die "Cannot open shadow file:$!\n";
while(<F>){
chomp;
@s = split /:/;
if ( $s[1] !~ /!/){
print "user: $s[0] not locked \n";
}
}
close(F);
以 root 身份使用。
【讨论】: