⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch15.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<HTML>



<HEAD>

   <TITLE>Chapter 15 -- Direct Access to System Facilities</TITLE>

   <META NAME="GENERATOR" CONTENT="Mozilla/3.0b5aGold (WinNT; I) [Netscape]">

</HEAD>

<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">

<H1><FONT COLOR=#FF0000>Chapter 15</FONT></H1>

<H1><B><FONT SIZE=5 COLOR=#FF0000>Direct Access to System Facilities</FONT></B>

</H1>

<P>

<HR WIDTH="100%"></P>

<P>

<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>

</FONT></FONT></H3>



<UL>

<LI><A HREF="#Introduction" >Introduction</A>

<LI><A HREF="#WorkingwithUNIXUsersandGroups" >Working with UNIX Users and Groups</A>

<UL>

<LI><A HREF="#Informationfrometcpasswdwithgetpwe" >Information from /etc/passwd with getpwent()</A>

<LI><A HREF="#GettingGroupRelatedInformationwithg" >Getting Group-Related Information with getgrent() and getgrnam()</A>

</UL>

<LI><A HREF="#GettingInformationinNetworkFiles" >Getting Information in Network Files</A>

<UL>

<LI><A HREF="#ThegetnetentFunction" >The getnetent Function</A>

<LI><A HREF="#WorkingwithHostNamesUsinggethostbya" >Working with Host Names Using gethostbyaddr() Functions</A>

<LI><A HREF="#WorkingwithProcessGroupsUsingthege" >Working with Process Groups Using the getpgrp() Function</A>

</UL>

<LI><A HREF="#GettingandChangingthePriorityofaP" >Getting and Changing the Priority of a Process</A>

<UL>

<LI><A HREF="#ThesetpriorityFunction" >The setpriority Function</A>

<LI><A HREF="#ThegetpriorityFunction" >The getpriority Function</A>

<LI><A HREF="#WorkingwithProtocolFilesUsingthege" >Working with Protocol Files Using the getprotoent() Function</A>

<LI><A HREF="#ThegetserventFunction" >The getservent Function</A>

</UL>

<LI><A HREF="#SystemLevelFunctions" >System-Level Functions</A>

<UL>

<LI><A HREF="#ThechrootFunction" >The chroot Function</A>

<LI><A HREF="#ThedumpFunction" >The dump Function</A>

<LI><A HREF="#UsingtheioctlFunction" >Using the ioctl Function</A>

<LI><A HREF="#UsingtheselectCall" >Using the select Call</A>

<LI><A HREF="#ThesyscallFunction" >The syscall Function</A>

</UL>

<LI><A HREF="#Summary" >Summary</A>

</UL>

<HR>

<P>

Perl can be used to access system facilities not directly available

in shell or <TT><FONT FACE="Courier">awk</FONT></TT> programs.

This chapter discusses some of the ways in which Perl programs

can access system files and resources. The bulk of this chapter

provides information on accessing data structures within system

files on a UNIX system. In <A HREF="ch9.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch9.htm" >Chapter 9</A>, &quot;Portability

Issues with Windows and Perl,&quot; and <A HREF="ch10.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch10.htm" >Chapter 10</A>,

&quot;Win32 Modules on Windows NT,&quot; I discussed ways of accessing

files on an NT system when covering portability issues.

<H2><A NAME="Introduction"><FONT SIZE=5 COLOR=#FF0000>Introduction</FONT></A>

</H2>

<P>

Accessing system facilities enables you to add that extra spice

to your Perl programs. You have already seen how to call UNIX

programs with the back quote (<TT><FONT FACE="Courier">`</FONT></TT>)

operators or the <TT><FONT FACE="Courier">system()</FONT></TT>

call. Both these mechanisms are costly in terms of using system

resources because they start a subshell to execute another process.

Perl offers many utilities to access system files and affects

process parameters (such as process priorities) without resorting

to firing up another process to perform a simple command.

<P>

Let's start with an example that shows you how to get more information

about the user running your Perl program. Sometimes it might be

nice to personalize your Perl scripts by sending messages back

to the user running your script. It's easy to derive the user

name from the <TT><FONT FACE="Courier">/etc/passwd</FONT></TT>

file or from calling the <TT><FONT FACE="Courier">getlogin()</FONT></TT>

function. Here's the syntax for the <TT><FONT FACE="Courier">getlogin()</FONT></TT>

function:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$userName = getlogin();</FONT></TT>

</BLOCKQUOTE>

<P>

<TT><FONT FACE="Courier">$userName</FONT></TT> is the returned

user ID. For example, you could write a script to get the name

and print out an appropriate greeting based on the user name:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$logname = getlogin();<BR>

if ($logname == &quot;khusain&quot;) {<BR>

</FONT></TT>&nbsp;&nbsp;&nbsp;&nbsp;<TT><FONT FACE="Courier">&nbsp;&nbsp;&nbsp;&nbsp;print

(&quot;Hello, Kamran! How are you?\n&quot;);<BR>

} else {<BR>

if ($logname == &quot;mgr2&quot;) {<BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print (&quot;Oh

no, it's you again !! !!!! !!\n&quot;);<BR>

}</FONT></TT>

</BLOCKQUOTE>

<P>

I am sure that you can come up with more practical applications

rather than spewing greetings and salutations based on a user

name. Practical examples include getting files, mail, and so on

based on the user name. A number of utilities are available that

do such things as answer your mail while you're on vacation and

manage your mail from multiple sources. Check out the archives

at the various Perl archive sites listed in appendix B, &quot;Perl

Module Archives,&quot; for these files. Most of these utilities

are copyrighted by their authors, so they cannot be printed here,

but you will get a good idea of what they can do.

<H2><A NAME="WorkingwithUNIXUsersandGroups"><FONT SIZE=5 COLOR=#FF0000>Working

with UNIX Users and Groups</FONT></A></H2>

<P>

Perl is great for working with user and group information files

in the <TT><FONT FACE="Courier">/etc</FONT></TT> directory. You

can get user and group names, IDs, and other useful information

from within your Perl programs to create powerful system administration

applications.

<H3><A NAME="Informationfrometcpasswdwithgetpwe">Information from

<TT><FONT SIZE=4 FACE="Courier">/etc/passwd</FONT></TT><FONT SIZE=4>

with</FONT><TT><FONT SIZE=4 FACE="Courier"> getpwent()</FONT></TT></A>

</H3>

<P>

The <TT><FONT FACE="Courier">getpwent()</FONT></TT> function enables

you to access sequentially entries in the <TT><FONT FACE="Courier">/etc/passwd</FONT></TT>

file. Here's the syntax for the <TT><FONT FACE="Courier">getpwent</FONT></TT>

function:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">($username,<BR>

$password,<BR>

$userid,<BR>

$groupid,<BR>

$quota,<BR>

$comment,<BR>

$userInfo,<BR>

$userHome,<BR>

$loginShell) = getpwent();</FONT></TT>

</BLOCKQUOTE>

<P>

Here are the returned values from the <TT><FONT FACE="Courier">getpwent</FONT></TT>

call:<P>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR VALIGN=TOP><TD WIDTH=129><TT><FONT FACE="Courier">$username</FONT></TT>

</TD><TD WIDTH=275>Contains the login name of the user</TD></TR>

<TR VALIGN=TOP><TD WIDTH=129><TT><FONT FACE="Courier">$password</FONT></TT>

</TD><TD WIDTH=275>Contains the user's encrypted password</TD>

</TR>

<TR VALIGN=TOP><TD WIDTH=129><TT><FONT FACE="Courier">$userid</FONT></TT>

</TD><TD WIDTH=275>The user ID</TD></TR>

<TR VALIGN=TOP><TD WIDTH=129><TT><FONT FACE="Courier">$groupid</FONT></TT>

</TD><TD WIDTH=275>The group ID</TD></TR>

<TR VALIGN=TOP><TD WIDTH=129><TT><FONT FACE="Courier">$quota</FONT></TT>

</TD><TD WIDTH=275>System dependent and may not exist</TD></TR>

<TR VALIGN=TOP><TD WIDTH=129><TT><FONT FACE="Courier">$comment</FONT></TT>

</TD><TD WIDTH=275>System dependent and may not exist</TD></TR>

<TR VALIGN=TOP><TD WIDTH=129><TT><FONT FACE="Courier">$userInfo</FONT></TT>

</TD><TD WIDTH=275>Personal information about the user</TD></TR>

<TR VALIGN=TOP><TD WIDTH=129><TT><FONT FACE="Courier">$userHome</FONT></TT>

</TD><TD WIDTH=275>The user's home directory</TD></TR>

<TR VALIGN=TOP><TD WIDTH=129><TT><FONT FACE="Courier">$loginShell</FONT></TT>

</TD><TD WIDTH=275>The user's startup command shell</TD></TR>

</TABLE></CENTER>

<P>

<P>

To access each entry of the password file in turn, you can use

the <TT><FONT FACE="Courier">getpwent()</FONT></TT> function.

Calling the <TT><FONT FACE="Courier">getpwent()</FONT></TT> function

for the first time in a program returns the first item in the

<TT><FONT FACE="Courier">/etc/passwd</FONT></TT> file. Every subsequent

call to <TT><FONT FACE="Courier">getpwent()</FONT></TT>returns

the next entry in the file. The function returns an empty list

after reaching the last entry in the file. Calling the <TT><FONT FACE="Courier">getpwent()</FONT></TT>

function after an empty list is received returns the first item

in <TT><FONT FACE="Courier">/etc/passwd</FONT></TT>, and you can

start over. The <TT><FONT FACE="Courier">getpwent()</FONT></TT>

function has two related functions: <TT><FONT FACE="Courier">setpwent()</FONT></TT>

to rewind the file and <TT><FONT FACE="Courier">endpwent()</FONT></TT>

to close the <TT><FONT FACE="Courier">/etc/passwd</FONT></TT>

file. Here's the syntax for the <TT><FONT FACE="Courier">setpwent</FONT></TT>

function:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">setpwent (keepopen);</FONT></TT>

</BLOCKQUOTE>

<P>

If <TT><FONT FACE="Courier">keepopen</FONT></TT> is non-zero,

the <TT><FONT FACE="Courier">/etc/passwd</FONT></TT> file is left

open for reading and any previously cached information about the

file is kept in memory. If <TT><FONT FACE="Courier">keepopen</FONT></TT>

is set to zero, any cached information in memory is flushed and

the file is read again with the first entry available for a call

to <TT><FONT FACE="Courier">getpwent()</FONT></TT>. The <TT><FONT FACE="Courier">endpwent</FONT></TT>

function simply closes the <TT><FONT FACE="Courier">/etc/password</FONT></TT>

file.

<P>

Listing 15.1 uses <TT><FONT FACE="Courier">getpwent</FONT></TT>

to list the user names known by the machine as well as their user

IDs.

<HR>

<BLOCKQUOTE>

<B>Listing 15.1. Listing password entries.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #!/usr/bin/perl<BR>

&nbsp;2<BR>

&nbsp;3&nbsp;&nbsp;while

(1) {<BR>

&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;last

unless (($username, $password, $userid)<BR>

&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=

getpwent());<BR>

&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$users{$username}

= $userid;<BR>

&nbsp;7&nbsp;&nbsp;}<BR>

&nbsp;8&nbsp;&nbsp;print (&quot;Users on this machine:\n&quot;);

<BR>

&nbsp;9<BR>

10&nbsp;&nbsp;foreach $user (sort keys (%users)) {<BR>

11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf

(&quot;%-20s %d\n&quot;, $user, $users{$user});<BR>

12&nbsp;&nbsp;}</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

The <TT><FONT FACE="Courier">while</FONT></TT> loop in this listing

calls <TT><FONT FACE="Courier">getpwent()</FONT></TT> to read

every entry in the <TT><FONT FACE="Courier">/etc/password</FONT></TT>

file. For this script, we are using only the first three elements

of the returned list: the users' names, their encrypted passwords,

and their IDs. The values are stored in the <TT><FONT FACE="Courier">%users</FONT></TT>

associative array and displayed in the <TT><FONT FACE="Courier">for()</FONT></TT>

loop. The output should look like this:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">Users on this machine:<BR>

adm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3

<BR>

bin&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1

<BR>

daemon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2

<BR>

ftp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;404

<BR>

games&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12

<BR>

guest&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;405

<BR>

halt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7

<BR>

khusain&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;501

<BR>

lp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4

<BR>

mail&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8

<BR>

man&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13

<BR>

news&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9

<BR>

nobody&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;65535

<BR>

operator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;11

<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -