Provided by: manpages-zh_1.5.1-1_all bug

NAME

       perlfaq8 - 系统交互 (2003/01/26 17:44:04 )

DESCRIPTION述
       Perl FAQ 的这一节覆盖了与系统交互有关的问题。主题包括进程间通信
       (IPC),用户界面控制
       (键盘,屏幕和指点设备),以及其他与数据操作不相关的事项

       阅读你系统中的 perl 自带的 FAQ 和文档
       (例如,perlvms,perlplan9...)。它们会包含有关你的 perl
       版本的更详细的信息。

      ?

       exec()?

       因为这正是它所做的:它用另一个不同的程式来取代你当时所执行的。如果你的程
       式需要继续跑下去(这可能正是你问此问题的砸虬桑浚挠 system() 。

      ?

       连接/控制 键盘、萤幕和指标装置(「滑鼠」)的方法因作业系统的不同而有不
       同;不妨试试下列模组:

       Keyboard
               Term::Cap                   标准内建模组
               Term::ReadKey               CPAN
               Term::ReadLine::Gnu         CPAN
               Term::ReadLine::Perl        CPAN
               Term::Screen                CPAN

       Screen
               Term::Cap                   标准内建模组
               Curses                      CPAN
               Term::ANSIColor             CPAN

       Mouse
               Tk                          CPAN

       Some of these specific cases are shown below.

       How do I print something out in color?

       In general, you don't, because you don't know whether the recipient has
       a color-aware display device.  If you know that they have an ANSI
       terminal that understands color, you can use the Term::ANSIColor module
       from CPAN:

           use Term::ANSIColor;
           print color("red"), "Stop!\n", color("reset");
           print color("green"), "Go!\n", color("reset");

       Or like this:

           use Term::ANSIColor qw(:constants);
           print RED, "Stop!\n", RESET;
           print GREEN, "Go!\n", RESET;

       How do I read just one key without waiting for a return key?

       Controlling input buffering is a remarkably system-dependent matter.
       On many systems, you can just use the stty command as shown in "getc"
       in perlfunc, but as you see, that's already getting you into
       portability snags.

           open(TTY, "+</dev/tty") or die "no tty: $!";
           system "stty  cbreak </dev/tty >/dev/tty 2>&1";
           $key = getc(TTY);           # perhaps this works
           # OR ELSE
           sysread(TTY, $key, 1);      # probably this does
           system "stty -cbreak </dev/tty >/dev/tty 2>&1";

       The Term::ReadKey module from CPAN offers an easy-to-use interface that
       should be more efficient than shelling out to stty for each key.  It
       even includes limited support for Windows.

           use Term::ReadKey;
           ReadMode('cbreak');
           $key = ReadKey(0);
           ReadMode('normal');

       However, using the code requires that you have a working C compiler and
       can use it to build and install a CPAN module.  Here's a solution using
       the standard POSIX module, which is already on your systems (assuming
       your system supports POSIX).

           use HotKey;
           $key = readkey();

       And here's the HotKey module, which hides the somewhat mystifying calls
       to manipulate the POSIX termios structures.

           # HotKey.pm
           package HotKey;

           @ISA = qw(Exporter);
           @EXPORT = qw(cbreak cooked readkey);

           use strict;
           use POSIX qw(:termios_h);
           my ($term, $oterm, $echo, $noecho, $fd_stdin);

           $fd_stdin = fileno(STDIN);
           $term     = POSIX::Termios->new();
           $term->getattr($fd_stdin);
           $oterm     = $term->getlflag();

           $echo     = ECHO | ECHOK | ICANON;
           $noecho   = $oterm & ~$echo;

           sub cbreak {
               $term->setlflag($noecho);  # ok, so i don't want echo either
               $term->setcc(VTIME, 1);
               $term->setattr($fd_stdin, TCSANOW);
           }

           sub cooked {
               $term->setlflag($oterm);
               $term->setcc(VTIME, 0);
               $term->setattr($fd_stdin, TCSANOW);
           }

           sub readkey {
               my $key = '';
               cbreak();
               sysread(STDIN, $key, 1);
               cooked();
               return $key;
           }

           END { cooked() }

           1;

       How do I check whether input is ready on the keyboard?

       The easiest way to do this is to read a key in nonblocking mode with
       the Term::ReadKey module from CPAN, passing it an argument of -1 to
       indicate not to block:

           use Term::ReadKey;

           ReadMode('cbreak');

           if (defined ($char = ReadKey(-1)) ) {
               # input was waiting and it was $char
           } else {
               # no input was waiting
           }

           ReadMode('normal');                  # restore normal tty settings

       How do I clear the screen?

       If you only have do so infrequently, use "system":

           system("clear");

       If you have to do this a lot, save the clear string so you can print it
       100 times without calling a program 100 times:

           $clear_string = `clear`;
           print $clear_string;

       If you're planning on doing other screen manipulations, like cursor
       positions, etc, you might wish to use Term::Cap module:

           use Term::Cap;
           $terminal = Term::Cap->Tgetent( {OSPEED => 9600} );
           $clear_string = $terminal->Tputs('cl');

       How do I get the screen size?

       If you have Term::ReadKey module installed from CPAN, you can use it to
       fetch the width and height in characters and in pixels:

           use Term::ReadKey;
           ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();

       This is more portable than the raw "ioctl", but not as illustrative:

           require 'sys/ioctl.ph';
           die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
           open(TTY, "+</dev/tty")                     or die "No tty: $!";
           unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
               die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
           }
           ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
           print "(row,col) = ($row,$col)";
           print "  (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel;
           print "\n";

      ?

       (这个问题跟全球资讯网一点关系也没有。如果你要找的是跟 WWW 有关的,那就
       看另一份常见问题集吧。)

       在 perlfunc 中的 "crypt"
       里面有个范例。首先,将你的终端机设为「无回应」"no echo"
       模式,然後就用平常的方法将密码读入。你可以用老式的 ioctl() 函数、 POSIX
       终端机控制函数(参看 POSIX ,和骆驼书第七章),或是呼叫 stty
       程式,这些方法的可携性/移植性程度都不一样。

       你也可以在大部份系统上使用 CPAN 里的 Term::ReadKey
       模组,这个模组较易使用而且理论上也较据可携性/移植性。

           use Term::ReadKey;

           ReadMode('noecho');
           $password = ReadLine(0);

      ?

       这端看你在什麽作业系统上执行你的程式。以 Unix 来说,序列埠可以透过 /dev
       目录下的档案来撷取;
       而在其他系统上,设备的名称无疑地会不一样。以下是一些在设备互动时可能遭遇的共同问题:

       lockfiles
           你的系统可能会使用锁档来控制多重读写的情况。确定你用的是正确的-
           定。因为当多个程序同时对一个装置做读取时可能会发生意想不到的情况。

       open mode
           如果你打算对一个装置同时做读与写的动作,你得将它开到更新的模式( 在
           perlfunc 中的 open
           里有更详细的解说)。如果你不希望冒着阻挡其他程序读取
           这个装置的风险,那就得用 sysopen() 和 Fcntl 模组(标准 perl
           的一部分)内 的 "O_RDWR|O_NDELAY|O_NOCTTY"。在 perlfunc 中的
           sysopen 里有对此方法更 详尽的解说。

       end of line
           有些装置会等着在每行结尾处看到一个 "\r",而非 "\n"。在某些平台上的
           perl, "\r"和 "\n" 与它们平常(在 Unix 上)所指的 ASCII 值 "\015"
           和 "\012" 有 所不同。你也许得直接给定数值,例如用八进位
           ("\015")、十六进位 ("0x0D"), 或指定控制字元 ("\cM")。

               print DEV "atv1\012";       # wrong, for some devices
               print DEV "atv1\015";       # right, for some devices

           尽管对普通的文字档案,一个 "\n"
           便可解决断行的问题,但目前在不同作业系统 间(Unix、DOS/Win 和
           Macintosh),对於断行记号仍无统一标准,而只有用 "\015\012" 来当成
           每行的结尾,然後再视需要去掉输出中不想要的部份。这 个做法尤其常用於
           socket输出/输入 与自动刷新 (autoflushing),也是接下来
           要讨论的主题。

       flushing output
           如果你希望 print()
           的时候每个字元都要送到你指定的装置去,那你应自动刷新文件句柄。可以使用
           select() 和 $| 变量控制自动刷新,参见 perlvar 中的 "$|" 和 perlfunc
           中的 "select",或 perlfaq5, ``How do I flush/unbuffer an output
           filehandle?  Why must I do this?''):

               $oldh = select(DEV);
               $| = 1;
               select($oldh);

           你也可能看到不使用额外的暂存变数的写法,例如:

               select((select(DEV), $| = 1)[0]);

           Or if you don't mind pulling in a few thousand lines of code just
           because you're afraid of a little $| variable:

               use IO::Handle;
               DEV->autoflush(1);

           As mentioned in the previous item, this still doesn't work when
           using socket I/O between Unix and Macintosh.  You'll need to hard
           code your line terminators, in that case.

       non-blocking input
           如果你正在做一个阻塞的 read() 或 sysread() 动作,则你需要安排一个闹
           铃把手或提供一个逾时设定(参看 alarm)。如果你是用非阻挡式的
           开档,那麽就要配合非阻挡性的读取,也就是说得用到4 个参数的 select()
           来确 定此装置的 输出/入 是否已准备好了(参考 perlfunc 中的 select
           )。

       While trying to read from his caller-id box, the notorious Jamie
       Zawinski <jwz@netscape.com>, after much gnashing of teeth and fighting
       with sysread, sysopen, POSIX's tcgetattr business, and various other
       functions that go bump in the night, finally came up with this:

           sub open_modem {
               use IPC::Open2;
               my $stty = `/bin/stty -g`;
               open2( \*MODEM_IN, \*MODEM_OUT, "cu -l$modem_device -s2400 2>&1");
               # starting cu hoses /dev/tty's stty settings, even when it has
               # been opened on a pipe...
               system("/bin/stty $stty");
               $_ = <MODEM_IN>;
               chomp;
               if ( !m/^Connected/ ) {
                   print STDERR "$0: cu printed `$_' instead of `Connected'\n";
               }
           }

      ?

       花大把大把的钱去买破解专用的硬体,这会让你成为焦点话题。

       说正镜模绻桥龅 Unix 密码档的话就不行 - Unix 密码系统用的是单向的加
       密函数。像 Crack 之类的程式可以暴力地(并聪明地)试着猜出密码,但无法
       (也不能)保证速战速决。

       如果你耽心的是使用者选取不良的密码,你应该在使用者换密码时主动审核(例如说修改
       passwd(1) 程式加入这个功能)。

      ?

       Several modules can start other processes that do not block your Perl
       program.  You can use IPC::Open3, Parallel::Jobs, IPC::Run, and some of
       the POE modules.  See CPAN for more details.

       你可以使用:

           system("cmd &")

       或是用 fork,像 perlfunc 中的 fork 里写的(在 perlipc 里有更进一步的
       范例)。如果你在 Unix 类的系统上的话,请注意以下几件事情:

       STDIN, STDOUT, and STDERR are shared
           主程序和背景程序(即「子」程序)共用同一个 STDIN、STDOUT 和 STDERR
           档案
           把手。如果两个程序想同时去读、写同一个档案把手,就可能有怪事会发生。你也
           许应该替子程序关闭或重新开启这些把手。你可以用开启一个管道 (pipe)
           的方法 避免这些问题(参看 open)但是在某些系统上这样做会强迫子程序
           必须比父程序早死。

       信号
           SIGCHLD、可能还有 SIGPIPE
           这两个讯号要抓到。当背景程序执行完成後就会送出 SIGCHLD
           讯号。而当你写入一个子程序已竟乇盏牡蛋赴咽质本突崾盏 SIGPIPE
           讯号(一个未抓住的 SIGPIPE 可能导致你的程式无声无息地死去)。用
           system("cmd&") 的话不会有这样的问题。

       僵尸进程
           你得做准备,在子程序结束时「收成」它:

               $SIG{CHLD} = sub { wait };

               $SIG{CHLD} = 'IGNORE';

           You can also use a double fork. You immediately wait() for your
           first child, and the init daemon will wait() for your grandchild
           once it exits.

                   unless ($pid = fork) {
                           unless (fork) {
                       exec "what you really wanna do";
                       die "exec failed!";
                           }
                   exit 0;
                   }
               waitpid($pid,0);

           在 Signals 有范例程式教你怎麽做。用 system("prog &") 的 话不会有僵
           程序的问题。

      /Unix shadow?

       如果你的 perl 安装正确的话,在 perlfunc 里描述的 getpw*()
       函数应该就能够读取隐式密码档了(只有读取权)。要更动该档案内容,做一个新的密码档(这个档案的格式因系统而异,请看
       passwd(5) )然後用 pwd_mkdb(8)(参考 pwd_mkdb(5))来安装新的密码档。

      ?

       假设你有足够的权限,你应该可以用 date(1) 程式来设定系统的时间与日期。
       (但没有针对个别程序修改时间日期的方法)这机制在 Unix、MS-DOS、Windows
       和 NT 下都能用;VMS 下则要用 set time 。

       然而,如果你只是要更动你的时区,只消设定一个环境变数即可:

           $ENV{TZ} = "MST7MDT";                  # unixish
           $ENV{'SYS$TIMEZONE_DIFFERENTIAL'}="-5" # vms
           system "trn comp.lang.perl.misc";

       sleep() alarm()?

       如果你要比 sleep() 所提供的最小单位一秒更精细的话,最简单的方法就是用
       select 里面写的 select() 函数。试一试 Time::HiRes 和 BSD::Itimer 模块
       (可以从 CPAN 下载,从 Perl 5.8 开始 Time::HiRes 成为标准发行的一部分).

      ?

       一般来说,你可能做不到。 Time::HiRes 模组(CPAN 有,从 Perl 5.8
       开始成为标准发行的一部分)在某些系统上能达到此 功能。

       总之,你可能做不到。但是如果你的 Perl 支援 syscall() 函数并支援类似
       gettimeofday(2) 的系统呼叫,你也许可以这麽做:

           require 'sys/syscall.ph';

           $TIMEVAL_T = "LL";

           $done = $start = pack($TIMEVAL_T, ());

           syscall(&SYS_gettimeofday, $start, 0) != -1
                      or die "gettimeofday: $!";

              ##########################
              # DO YOUR OPERATION HERE #
              ##########################

           syscall( &SYS_gettimeofday, $done, 0) != -1
                  or die "gettimeofday: $!";

           @start = unpack($TIMEVAL_T, $start);
           @done  = unpack($TIMEVAL_T, $done);

           # fix microseconds
           for ($done[1], $start[1]) { $_ /= 1_000_000 }

           $delta_time = sprintf "%.4f", ($done[0]  + $done[1]  )
                                                   -
                                        ($start[0] + $start[1] );

       atexit()setjmp()/longjmp()socketsSystem V (Solaris)-
      ?

       有些 Sys-V 根底的系统,特别像 Solaris 2.X,已重新将一些标准的
       socket常数 定义过了。由於这些常数在各种架构下都是定值,所以在
       perl程式码中常被人写 死在里面。处理此问题的适当方式 是用 ``use Socket''
       来取得正确的值。

       须注意尽管 SunOS 和 Solaris
       在二进位执行档上相容,这些值是相异的。自己去 想为什麽吧。

       PerlCioctl()syscall()cpp(1)指令转换成内含副程式定义的档案,像
       &SYS_getitimer,你可
       以把它当做函数的参数。这样做并不怎麽完美,但通常可达成任务。简单的像
       errno.h 、syscall.h 和socket.h 这些档案都没问题,但像 ioctl.h
       这种较难的档案总是需要人工编肌R韵率前沧 *.ph 档案的步骤:

           1.  成为超级用户
           2.  cd /usr/include
           3.  h2ph *.h */*.h

       如果你的系统支援动态载入,那麽为了可移植性、而且合理的做法是使用
       h2xs(也 是 perl的标准配备)。这个工具将 C 标头档案转换成 Perl
       的衍伸档案 (extensions)。 h2xs 的入门要看 perlxstut 。

       如果你的系统不支援动态载入,你可能仍应使用 h2xs。参看 perlxstut 和
       MakeMaker (简单来说,就是用 make perl 、而非 make 来重
       建一份使用新的静态连结的 perl)。

       setuid perl(pipe)system()STDERRsh(1)) 重导的语法而非
       csh(1)的!至於为何 Perl 的 system()、反向引号和开管道都用 Bourne
       shell语法的砸颍稍谙轮氛业剑"Far More Than You Ever Wanted To Know",
       http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz .  要同时捕捉一个命令的
       STDERR 和 STDOUT:

           $output = `cmd 2>&1`;                       # either with backticks
           $pid = open(PH, "cmd 2>&1 |");              # or with an open pipe
           while (<PH>) { }                            #    plus a read

       To capture a command's STDOUT but discard its STDERR:

           $output = `cmd 2>/dev/null`;                # either with backticks
           $pid = open(PH, "cmd 2>/dev/null |");       # or with an open pipe
           while (<PH>) { }                            #    plus a read

       To capture a command's STDERR but discard its STDOUT:

           $output = `cmd 2>&1 1>/dev/null`;           # either with backticks
           $pid = open(PH, "cmd 2>&1 1>/dev/null |");  # or with an open pipe
           while (<PH>) { }                            #    plus a read

       To exchange a command's STDOUT and STDERR in order to capture the
       STDERR but leave its STDOUT to come out our old STDERR:

           $output = `cmd 3>&1 1>&2 2>&3 3>&-`;        # either with backticks
           $pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&-|");# or with an open pipe
           while (<PH>) { }                            #    plus a read

       To read both a command's STDOUT and its STDERR separately, it's easiest
       and safest to redirect them separately to files, and then read from
       those files when the program is done:

           system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr");

       Ordering is important in all these examples.  That's because the shell
       processes file descriptor redirections in strictly left to right order.

           system("prog args 1>tmpfile 2>&1");
           system("prog args 2>&1 1>tmpfile");

       The first command sends both standard out and standard error to the
       temporary file.  The second command sends only the old standard output
       there, and the old standard error shows up on the old standard out.

       open()open() contains shell metacharacters,
       perl fork()s, then exec()s a shell to decode the metacharacters and
       eventually run the desired program.  If the program couldn't be run,
       it's the shell that gets the message, not Perl. All your Perl program
       can find out is whether the shell itself could be successfully started.
       You can still capture the shell's STDERR and check it for error
       messages.  See "How can I capture STDERR from an external command?"
       elsewhere in this document, or use the IPC::Open3 module.

       If there are no shell metacharacters in the argument of open(), Perl
       runs the command directly, without using the shell, and can correctly
       report whether the command started.

      ?

       严格说起来,没啥不对。但从程式写作严谨与否来说,这样无法写出较易维护的程式码。Perl
       有多种方法可以运行外部命令。反引号只是其中一个;它收集命令的输出,在程序中加以应用。
       "system" 函数是另一个,它不这样做

       Writing backticks in your program sends a clear message to the readers
       of your code that you wanted to collect the output of the command.  Why
       send a clear message that isn't true?

       再看看下列这一行:

           `cat /etc/termcap`;

       你还没有指定输出,所以它会浪费记忆体(就那麽一下子)。另外你也忘了检查
       $? 看看程式是否正确的执行。即使你写成

           print `cat /etc/termcap`;

       但在大部份情况下,这本来可以、而且也应该写成

           system("cat /etc/termcap") == 0
               or die "cat program failed!";

       这样可快速地得到输出(一产生出来就会得到,不用等到最後),并且检查传回值。

       system() 同时具有直接决定是否先做 shell 万用字元 (wildcard)处理的功能,
       反向引号就不行。

       shellopen()。类似 system()exec() 的列表形式,不会进行 shell 转义。

          open( GREP, "-|", 'grep', @opts, $search_string, @filenames );
          chomp(@ok = <GREP>);
          close GREP;

       也可以这样:

           my @ok = ();
           if (open(GREP, "-|")) {
               while (<GREP>) {
                   chomp;
                   push(@ok, $_);
               }
               close GREP;
           } else {
               exec 'grep', @opts, $search_string, @filenames;
           }

       一如 system(),当你 exec() 一个序列时不会有 shell
       解译的情况发生。更多示例可以从 perlipc 的 "Safe Pipe Opens" 中找到。

       Note that if you're use Microsoft, no solution to this vexing issue is
       even possible.  Even if Perl were to emulate fork(), you'd still be
       stuck, because Microsoft does not have a argc/argv-style API.

       EOFnix^DS-DOS^ZSTDIN
      ?

       因为某些 stdio 的 set error 和 eof 旗标需要清除。你可以用 POSIX
       模组里定
       义的clearerr()。这是在技术上正确的解决之道。还有一些较不保险的方法:

       1   试着保存搜寻指标然後去找它,例如:

               $where = tell(LOG);
               seek(LOG, $where, 0);

       2   如果那样行不通,试着去 seek() 档案的另一部份然後再找回来。

       3   如果还是行不通,试着 seek()
           档案另一个相异的的部份,读点东西,再回去找。

       4   如果依然不行,放弃使用 stdio 改用 sysread。

       shellperlperltelnetftp?

       试试 Net::FTP、TCP::Client 和 NET::Telnet 模组(CPAN 有)。
       http://www.perl.com/CPAN/scripts/netstuff/telnet.emul.shar 也有助於模拟
       telnet 卸ǎ Net::Telnet 可能较容易使用。

       如果你所要做的只是假装 telnet 但又不要起始 telnet
       时的沟通程序,那麽以下这个标准的双程序方式就可以满足你的需要了:

           use IO::Socket;             # new in 5.004
           $handle = IO::Socket::INET->new('www.perl.com:80')
                   || die "can't connect to port 80 on www.perl.com: $!";
           $handle->autoflush(1);
           if (fork()) {               # XXX: undef means failure
               select($handle);
               print while <STDIN>;    # everything from stdin to socket
           } else {
               print while <$handle>;  # everything from socket to stdout
           }
           close $handle;
           exit;

       PerlExpectperlperl script{fork?

       如果你所指的是离线的程序(未与 tty 连线者),那下列的程序据说在大部份的
       Unix系统都能用。非 Unix 系统的使用者应该检查 Your_OS::Process
       模组看看有 没有其他的解决方案。

       o   打开 /dev/tty 然後对它用 TIOCNOTTY ioctl。请参考 tty(4)
           。更好的办法,你可以只用 POSIX::setsid() 函数,从而不必担心进程组。

       o   把目录换到 /

       o   重开 STDIN、STDOUT 和 STDERR 使它们不会与旧的 tty 连接。

       o   用下列方法把程式丢到后台:

               fork && exit;

       The Proc::Daemon module, available from CPAN, provides a function to
       perform these actions for you.

      ?

       问得好。有的时候 "-t STDIN"N 和 "-t STDOUT" 可以提供线索,有时不行。

           if (-t STDIN && -t STDOUT) {
               print "Now what? ";
           }

       在 POSIX 系统中,你可以用以下方法测试你自己的程序群组与现在控制你终端机
       的是否相同:

           use POSIX qw/getpgrp tcgetpgrp/;
           open(TTY, "/dev/tty") or die $!;
           $tpgrp = tcgetpgrp(fileno(*TTY));
           $pgrp = getpgrp();
           if ($tpgrp == $pgrp) {
               print "foreground\n";
           } else {
               print "background\n";
           }

      ?

       如同 Signals 和 Camel 书第六章里所描述的,用 alarm() 函数,
       或许再配合上一个讯号处理器。你也可以改用 CPAN 里更具弹性的
       Sys::AlarmCall 模组来做。

       The alarm() function is not implemented on all versions of Windows.
       Check the documentation for your specific version of Perl.

       CPU?

       使用 CPAN 里的 BSD::Resource 模组。

       Unix?

       使用 Signals 里面叫 reaper 的程式码,在接到 SIGCHLD 时会呼
       叫wait(),或是用 perlfaq8 中的 "How do I start a process in the
       background?" 里面写的双 fork 技巧。

       SQL?

       The DBI module provides an abstract interface to most database servers
       and types, including Oracle, DB2, Sybase, mysql, Postgresql, ODBC, and
       flat files.  The DBI module accesses each database type through a
       database driver, or DBD.  You can see a complete list of available
       drivers on CPAN: http://www.cpan.org/modules/by-module/DBD/ .  You can
       read more about DBI on http://dbi.perl.org .

       Other modules provide more specific access: Win32::ODBC, Alzabo, iodbc,
       and others found on CPAN Search: http://search.cpan.org .

       system() control-C?

       做不到。你需要摹仿 system() 呼叫(参看 perlipc
       里的范例程式),然後设计一个讯号处理器,让它把 INT
       讯号传给子程序。或者可以检测它:

           $rc = system($cmd);
           if ($rc & 127) { die "signal death" }

      ?

       如果你有幸使用到支援无阻塞读的系统(大部份 Unix 般的系统都有支援),
       你只需要用 Fcntl 模组里的 O_NDELAY 或 O_NONBLOCK 旗标,配合 sysopen():

           use Fcntl;
           sysopen(FH, "/tmp/somefile", O_WRONLY|O_NDELAY|O_CREAT, 0644)
               or die "can't open /tmp/somefile: $!":

       How do I install a module from CPAN?

       最简单的方法就是让 CPAN 这个模组替你代劳。这个模组包含在
       5.004及以後的版 本中。

           $ perl -MCPAN -e shell

           cpan shell -- CPAN exploration and modules installation (v1.59_54)
           ReadLine support enabled

           cpan> install Some::Module

       如要手动安装 CPAN 模组,或是任何按规矩发展的 CPAN模组,遵岩韵虏 骤:

       1   把源代码解压到临时目录

       2
               perl Makefile.PL

       3
               make

       4
               make test

       5
               make install

       如果你用的 perl 版本在编译时没有建入动态连结的功能,那你只消把第叁步
       (make)换成 make perl 然後你就会得到一个新的 perl 执行档,里头连
       有你新加入的延伸。

       在 ExtUtils::MakeMaker
       里面有更多关於建构模组的细节,并参考下一个问题,require 和 use
       的区别是什么?。

       require use?

       Perl offers several different ways to include code from one file into
       another.  Here are the deltas between the various inclusion constructs:

           1)  do $file is like eval `cat $file`, except the former
               1.1: searches @INC and updates %INC.
               1.2: bequeaths an *unrelated* lexical scope on the eval'ed code.

           2)  require $file is like do $file, except the former
               2.1: checks for redundant loading, skipping already loaded files.
               2.2: raises an exception on failure to find, compile, or execute $file.

           3)  require Module is like require "Module.pm", except the former
               3.1: translates each "::" into your system's directory separator.
               3.2: primes the parser to disambiguate class Module as an indirect object.

           4)  use Module is like require Module, except the former
               4.1: loads the module at compile time, not run-time.
               4.2: imports symbols and semantics from that package to the current one.

       In general, you usually want "use" and a proper Perl module.

      //include (@INC)?

       以下是我们建议更动引入路径的方法:

           环境变量 PERLLIB
           环境变量 PERL5LIB
           perl -Idir 命令行标志
           use lib 编用,类似
               use lib "$ENV{HOME}/myown_perllib";

       後者特别有用,因为它知道与机器相关的架构。lib.pm 机制模组是从 5.002
       版开 始包含在 Perl 里面的。

       socket.ph

AUTHOR AND COPYRIGHT

       Copyright (c) 1997-2003 Tom Christiansen and Nathan Torkington.  All
       rights reserved.

       This documentation is free; you can redistribute it and/or modify it
       under the same terms as Perl itself.

       Irrespective of its distribution, all code examples in this file are
       hereby placed into the public domain.  You are permitted and encouraged
       to use this code in your own programs for fun or for profit as you see
       fit.  A simple comment in the code giving credit would be courteous but
       is not required.

者
      室