在/ etc / passwd中搜索用户名

时间:2018-04-11 21:56:48

标签: regex perl

我试图在/etc/passwd文件中搜索用户输入的用户名,但我不确定if语句的语法。我目前的代码是:

print "Username?";
$username = <STDIN>;

open (PASSWD, '/etc/passwd')
     while (<PASSWD>);
          if (PASSWD ((split(/:/)[0] =~ $username)) {
               print ((split(/:/)[5]), "\n");
          }
close (PASSWD);

语法有问题,尽管我在搜索stackoverflow和google时遇到了困难,但仍然找不到正确的方法。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

Perl具有内置函数,请参阅getpwnamUser::pwent

use warnings;
use strict;

print "Username? ";
chomp( my $username = <STDIN> );

die "Unknown user $username\n" unless getpwnam($username);

my $dir = (getpwnam($username))[7];
print $dir, "\n";

# - or -
use User::pwent;
print getpwnam($username)->dir, "\n";

答案 1 :(得分:1)

我认为open()行末尾丢失的分号是拼写错误。

您的while语句需要一个块,而不是分号。

while (<PASSWD>) {
  ... # stuff
}

当您运行此行时:

$username = <STDIN>;

然后$username将包含用户在命令行输入的所有字符。至关重要的是,它包括按下“Enter”键时生成的换行符。

然后,您继续将该变量与/etc/passwd中记录中的第一个字段进行比较。这些字段不包含换行符,因此匹配永远不会成功。

您需要从$username的末尾删除换行符。这就是chomp()的用途。

chomp($username = <STDIN>);

此外,PASSWD声明中的if非常奇怪。我不确定你为什么认为这是必要的。不是。

if ( (split(/:/)[0] =~ $username) {

但实际上,正则表达式检查在这里是过度的。你应该检查字符串是否相等。

if ((split(/:/)[0] eq $username) {

其他一些提示:

  • 始终use strictuse warnings
  • 对文件句柄使用词法变量,使用open()的三参数版本并始终检查open()的返回值

    open my $passwd_fh, '<', '/etc/passwd'
      or die "Cannot open /etc/passwd: $!\n";