這些例程與系統C庫中的對應例程相同。在列表上下文中,各種獲取例程的返回值如下:
# 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,因此$gcos被污染(請參見perlsec)。由於同樣的原因,$passwd和$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_pwquota
、d_pwage
、d_pwchange
、d_pwcomment
和 d_pwexpire
在 Perl 中了解您的 $quota 和 $comment 字段的含义以及是否有 $expire 字段。只有在您的供应商以直观的方式实现了它们的情况下,才支持阴影密码文件。如果您以特权运行或者存在 System V 中的 shadow(3) 函数(包括 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::stat
, Net::hostent
, Net::netent
, Net::protoent
, Net::servent
, Time::gmtime
, Time::localtime
, 和 User::grent
。這些會覆蓋正常的內建函數,提供了返回具有每個字段適當名稱的對象的版本。例如
use File::stat;
use User::pwent;
my $is_his = (stat($filename)->uid == pwent($whoever)->uid);
儘管看起來它們是相同的方法調用(uid),但它們實際上並不相同,因為一個 File::stat
對象與一個 User::pwent
對象是不同的。
許多這些函數在多線程環境中不安全,其中可以有多個線程在使用它們。特別是,像 getpwent()
這樣的函數是逐進程迭代而不是逐線程的,所以如果兩個線程同時迭代,則都不會獲得所有記錄。
一些系統有一些函數的線程安全版本,例如 getpwnam()
的線程安全版本是 getpwnam_r()
。在這種情況下,Perl會自動並隱藏地替換線程安全版本,而不會通知。這意味著在一些系統上安全運行的代碼可能在缺乏線程安全版本的其他系統上失敗。