這些例程與系統 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
(如果項目不存在,回傳值為單一無意義的 true 值。)
$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_pwquota
、d_pwage
、d_pwchange
、d_pwcomment
和 d_pwexpire
,從 Perl 中找出 $quota 和 $comment 欄位的含義,以及您是否有 $expire 欄位。只有當供應商以直覺的方式實作影子密碼檔案時,才會支援影子密碼檔案,也就是說,如果您在特權下執行,或存在 shadow(3) 函式(如在 System V 中找到的),則呼叫常規 C 函式庫常式會取得影子版本(這包括 Solaris 和 Linux)。實作專有影子密碼設施的系統不太可能獲得支援。
getgr*() 傳回的 $members 值是群組成員的登入名稱的空格分隔清單。
對於 gethost*() 函式,如果 C 中支援 h_errno
變數,如果函式呼叫失敗,它會透過 $?
傳回給您。成功呼叫傳回的 @addrs
值是對應函式庫呼叫傳回的原始位址清單。在網際網路網域中,每個位址長度為四個位元組;您可以透過說類似
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
在 SCALAR 背景中呼叫,並且檢查其傳回值是否已定義。
即使 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_r()
而不是 getpwnam()
。在這種情況下,Perl 會自動且無形地替換執行緒安全版本,而不會通知。這表示在某些系統上安全執行的程式碼可能會在缺少執行緒安全版本的其他系統上失敗。
可移植性問題:perlport 中的「getpwnam」 到 perlport 中的「endservent」。