getpwnam NAME
getgrnam NAME
gethostbyname NAME
getnetbyname NAME
getprotobyname NAME
getpwuid UID
getgrgid GID
getservbyname NAME,PROTO
gethostbyaddr ADDR,ADDRTYPE
getnetbyaddr ADDR,ADDRTYPE
getprotobynumber NUMBER
getservbyport PORT,PROTO
getpwent
getgrent
gethostent
getnetent
getprotoent
getservent
setpwent
setgrent
sethostent STAYOPEN
setnetent STAYOPEN
setprotoent STAYOPEN
setservent STAYOPEN
endpwent
endgrent
endhostent
endnetent
endprotoent
endservent

这些例程与系统 C 库中的对应例程相同。在列表上下文中,各种 get 例程的返回值如下

#    0        1          2           3         4
my ( $name,   $passwd,   $gid,       $members  ) = getgr*
my ( $name,   $aliases,  $addrtype,  $net      ) = getnet*
my ( $name,   $aliases,  $port,      $proto    ) = getserv*
my ( $name,   $aliases,  $proto                ) = getproto*
my ( $name,   $aliases,  $addrtype,  $length,  @addrs ) = gethost*
my ( $name,   $passwd,   $uid,       $gid,     $quota,
   $comment,  $gcos,     $dir,       $shell,   $expire ) = getpw*
#    5        6          7           8         9

(如果条目不存在,则返回值为单个无意义的真值。)

$gcos 字段的具体含义各不相同,但通常包含用户的真实姓名(与登录名相反)以及与用户相关的其他信息。但是,请注意,在许多系统中,用户能够更改此信息,因此无法信任它,因此 $gcos 被污染(参见 perlsec)。$passwd 和 $shell,用户的加密密码和登录 shell,也由于相同的原因而被污染。

在标量上下文中,您将获得名称,除非该函数是按名称查找,在这种情况下,您将获得其他内容,无论是什么。(如果条目不存在,您将获得未定义的值。)例如

my $uid   = getpwnam($name);
my $name  = getpwuid($num);
my $name  = getpwent();
my $gid   = getgrnam($name);
my $name  = getgrgid($num);
my $name  = getgrent();
# etc.

getpw*() 中,字段 $quota、$comment 和 $expire 是特殊的,因为它们在许多系统上不受支持。如果 $quota 不受支持,它是一个空标量。如果它受支持,它通常会编码磁盘配额。如果 $comment 字段不受支持,它是一个空标量。如果它受支持,它通常会编码有关用户的某些管理注释。在某些系统中,$quota 字段可能是 $change 或 $age,这些字段与密码老化有关。在某些系统中,$comment 字段可能是 $class。$expire 字段(如果存在)会编码帐户或密码的过期时间。有关这些字段在您的系统中的可用性和确切含义,请参阅 getpwnam(3) 和您系统的 pwd.h 文件。您还可以使用 Config 模块和值 d_pwquotad_pwaged_pwchanged_pwcommentd_pwexpire 从 Perl 中找出您的 $quota 和 $comment 字段的含义以及您是否具有 $expire 字段。影子密码文件仅在您的供应商以直观的方式实现它们时才受支持,即调用常规 C 库例程会在您以特权身份运行时获取影子版本,或者如果存在 shadow(3) 函数(如 System V 中的函数)(这包括 Solaris 和 Linux)。那些实现专有影子密码工具的系统不太可能得到支持。

getgr*() 返回的 $members 值是组成员登录名的空格分隔列表。

对于 gethost*() 函数,如果 C 中支持 h_errno 变量,则在函数调用失败时,它将通过 $? 返回给您。成功调用返回的 @addrs 值是对应库调用返回的原始地址列表。在 Internet 域中,每个地址都是四个字节长;您可以通过以下方式解包它

my ($w,$x,$y,$z) = unpack('W4',$addr[0]);

Socket 库使这变得更加容易

use Socket;
my $iaddr = inet_aton("127.1"); # or whatever address
my $name  = gethostbyaddr($iaddr, AF_INET);

# or going the other way
my $straddr = inet_ntoa($iaddr);

相反,要将主机名解析为 IP 地址,您可以编写以下代码

use Socket;
my $packed_ip = gethostbyname("www.perl.org");
my $ip_address;
if (defined $packed_ip) {
    $ip_address = inet_ntoa($packed_ip);
}

确保 gethostbyname 在标量上下文中调用,并检查其返回值是否已定义。

尽管 getprotobynumber 函数只接受一个参数,但它具有列表运算符的优先级,因此请注意

getprotobynumber $number eq 'icmp'   # WRONG
getprotobynumber($number eq 'icmp')  # actually means this
getprotobynumber($number) eq 'icmp'  # better this way

如果您厌倦了记住返回列表中的哪个元素包含哪个返回值,标准模块中提供了按名称的接口:File::statNet::hostentNet::netentNet::protoentNet::serventTime::gmtimeTime::localtimeUser::grent。这些覆盖了正常的内置函数,提供了返回具有每个字段的适当名称的对象的版本。例如

use File::stat;
use User::pwent;
my $is_his = (stat($filename)->uid == pwent($whoever)->uid);

尽管它们看起来像是相同的调用方法(uid),但它们并不相同,因为 File::stat 对象与 User::pwent 对象不同。

许多这些函数在多线程环境中不安全,在多线程环境中,多个线程可以使用它们。特别是,像 getpwent() 这样的函数是按进程迭代的,而不是按线程迭代的,因此如果两个线程同时迭代,它们都不会获得所有记录。

一些系统为某些函数提供了线程安全的版本,例如使用 `getpwnam_r()` 代替 `getpwnam()`。在这些情况下,Perl 会自动且隐式地替换为线程安全的版本,而不会发出任何通知。这意味着在某些系统上安全运行的代码在缺少线程安全版本的其他系统上可能会失败。

可移植性问题:"perlport 中的 getpwnam""perlport 中的 endservent"