Imported upstream version 1.5
[manpages-zh.git] / src / man1 / perlfaq8.1
blob2d923f6f82d0544b8b531f575e01f2c77a5f18bd
1 .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
2 .\"
3 .\" Standard preamble:
4 .\" ========================================================================
5 .de Sh \" Subsection heading
6 .br
7 .if t .Sp
8 .ne 5
9 .PP
10 \fB\\$1\fR
11 .PP
13 .de Sp \" Vertical space (when we can't use .PP)
14 .if t .sp .5v
15 .if n .sp
17 .de Vb \" Begin verbatim text
18 .ft CW
19 .nf
20 .ne \\$1
22 .de Ve \" End verbatim text
23 .ft R
24 .fi
26 .\" Set up some character translations and predefined strings.  \*(-- will
27 .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
28 .\" double quote, and \*(R" will give a right double quote.  | will give a
29 .\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
30 .\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
31 .\" expand to `' in nroff, nothing in troff, for use with C<>.
32 .tr \(*W-|\(bv\*(Tr
33 .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
34 .ie n \{\
35 .    ds -- \(*W-
36 .    ds PI pi
37 .    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
38 .    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
39 .    ds L" ""
40 .    ds R" ""
41 .    ds C` ""
42 .    ds C' ""
43 'br\}
44 .el\{\
45 .    ds -- \|\(em\|
46 .    ds PI \(*p
47 .    ds L" ``
48 .    ds R" ''
49 'br\}
50 .\"
51 .\" If the F register is turned on, we'll generate index entries on stderr for
52 .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
53 .\" entries marked with X<> in POD.  Of course, you'll have to process the
54 .\" output yourself in some meaningful fashion.
55 .if \nF \{\
56 .    de IX
57 .    tm Index:\\$1\t\\n%\t"\\$2"
59 .    nr % 0
60 .    rr F
61 .\}
62 .\"
63 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
64 .\" way too many mistakes in technical documents.
65 .hy 0
66 .if n .na
67 .\"
68 .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
69 .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
70 .    \" fudge factors for nroff and troff
71 .if n \{\
72 .    ds #H 0
73 .    ds #V .8m
74 .    ds #F .3m
75 .    ds #[ \f1
76 .    ds #] \fP
77 .\}
78 .if t \{\
79 .    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
80 .    ds #V .6m
81 .    ds #F 0
82 .    ds #[ \&
83 .    ds #] \&
84 .\}
85 .    \" simple accents for nroff and troff
86 .if n \{\
87 .    ds ' \&
88 .    ds ` \&
89 .    ds ^ \&
90 .    ds , \&
91 .    ds ~ ~
92 .    ds /
93 .\}
94 .if t \{\
95 .    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
96 .    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
97 .    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
98 .    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
99 .    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
100 .    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
102 .    \" troff and (daisy-wheel) nroff accents
103 .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
104 .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
105 .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
106 .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
107 .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
108 .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
109 .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
110 .ds ae a\h'-(\w'a'u*4/10)'e
111 .ds Ae A\h'-(\w'A'u*4/10)'E
112 .    \" corrections for vroff
113 .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
114 .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
115 .    \" for low resolution devices (crt and lpr)
116 .if \n(.H>23 .if \n(.V>19 \
118 .    ds : e
119 .    ds 8 ss
120 .    ds o a
121 .    ds d- d\h'-1'\(ga
122 .    ds D- D\h'-1'\(hy
123 .    ds th \o'bp'
124 .    ds Th \o'LP'
125 .    ds ae ae
126 .    ds Ae AE
128 .rm #[ #] #H #V #F C
129 .\" ========================================================================
131 .IX Title "PERLFAQ8 1"
132 .TH PERLFAQ8 1 "2003-11-25" "perl v5.8.3" "Perl Programmers Reference Guide"
133 .SH "NAME"
134 perlfaq8 \- 系统交互 (2003/01/26 17:44:04 )
135 .SH "DESCRIPTION 描述"
136 .IX Header "DESCRIPTION"
137 Perl FAQ 的这一节覆盖了与系统交互有关的问题。主题包括进程间通信 (IPC),用户界面控制 (键盘,屏幕和指点设备),以及其他与数据操作不相关的事项
139 阅读你系统中的 perl 自带的 FAQ 和文档 (例如,perlvms,perlplan9...)。它们会包含有关你的 perl 版本的更详细的信息。
140 .Sh "如何找出正在运行的操作系统?"
141 .IX Subsection "How do I find out which operating system I'm running under?"$^O 这个变数(若使用 English 模组就是 $OSTYPE)会指出你的 perl 解译器执 行档是替哪个作业系统、平台所建的。
142 .Sh "为什么 exec() 不返回?"
143 .IX Subsection "How come exec() doesn't return?"
144 因为这正是它所做的:它用另一个不同的程式来取代你当时所执行的。如果你的程 式需要继续跑下去(这可能正是你问此问题的原因吧?),改用 system() 。
145 .Sh "如何对键盘/萤幕/滑鼠做些花样?"
146 .IX Subsection "How do I do fancy stuff with the keyboard/screen/mouse?"
147 连接/控制 键盘、萤幕和指标装置(「滑鼠」)的方法因作业系统的不同而有不 同;不妨试试下列模组:
148 .IP "Keyboard" 4
149 .IX Item "Keyboard"
150 .Vb 5
151 \&    Term::Cap                   标准内建模组
152 \&    Term::ReadKey               CPAN
153 \&    Term::ReadLine::Gnu         CPAN
154 \&    Term::ReadLine::Perl        CPAN
155 \&    Term::Screen                CPAN
157 .IP "Screen" 4
158 .IX Item "Screen"
159 .Vb 3
160 \&    Term::Cap                   标准内建模组
161 \&    Curses                      CPAN
162 \&    Term::ANSIColor             CPAN
164 .IP "Mouse" 4
165 .IX Item "Mouse"
166 .Vb 1
167 \&    Tk                          CPAN
170 Some of these specific cases are shown below.
171 .Sh "How do I print something out in color?"
172 .IX Subsection "How do I print something out in color?"
173 In general, you don't, because you don't know whether
174 the recipient has a color-aware display device.  If you
175 know that they have an \s-1ANSI\s0 terminal that understands
176 color, you can use the Term::ANSIColor module from \s-1CPAN:\s0
178 .Vb 3
179 \&    use Term::ANSIColor;
180 \&    print color("red"), "Stop!\en", color("reset");
181 \&    print color("green"), "Go!\en", color("reset");
184 Or like this:
186 .Vb 3
187 \&    use Term::ANSIColor qw(:constants);
188 \&    print RED, "Stop!\en", RESET;
189 \&    print GREEN, "Go!\en", RESET;
191 .Sh "How do I read just one key without waiting for a return key?"
192 .IX Subsection "How do I read just one key without waiting for a return key?"
193 Controlling input buffering is a remarkably system-dependent matter.
194 On many systems, you can just use the \fBstty\fR command as shown in
195 \&\*(L"getc\*(R" in perlfunc, but as you see, that's already getting you into
196 portability snags.
198 .Vb 6
199 \&    open(TTY, "+</dev/tty") or die "no tty: $!";
200 \&    system "stty  cbreak </dev/tty >/dev/tty 2>&1";
201 \&    $key = getc(TTY);           # perhaps this works
202 \&    # OR ELSE
203 \&    sysread(TTY, $key, 1);      # probably this does
204 \&    system "stty -cbreak </dev/tty >/dev/tty 2>&1";
207 The Term::ReadKey module from \s-1CPAN\s0 offers an easy-to-use interface that
208 should be more efficient than shelling out to \fBstty\fR for each key.
209 It even includes limited support for Windows.
211 .Vb 4
212 \&    use Term::ReadKey;
213 \&    ReadMode('cbreak');
214 \&    $key = ReadKey(0);
215 \&    ReadMode('normal');
218 However, using the code requires that you have a working C compiler
219 and can use it to build and install a \s-1CPAN\s0 module.  Here's a solution
220 using the standard \s-1POSIX\s0 module, which is already on your systems
221 (assuming your system supports \s-1POSIX\s0).
223 .Vb 2
224 \&    use HotKey;
225 \&    $key = readkey();
228 And here's the HotKey module, which hides the somewhat mystifying calls
229 to manipulate the \s-1POSIX\s0 termios structures.
231 .Vb 2
232 \&    # HotKey.pm
233 \&    package HotKey;
236 .Vb 2
237 \&    @ISA = qw(Exporter);
238 \&    @EXPORT = qw(cbreak cooked readkey);
241 .Vb 3
242 \&    use strict;
243 \&    use POSIX qw(:termios_h);
244 \&    my ($term, $oterm, $echo, $noecho, $fd_stdin);
247 .Vb 4
248 \&    $fd_stdin = fileno(STDIN);
249 \&    $term     = POSIX::Termios->new();
250 \&    $term->getattr($fd_stdin);
251 \&    $oterm     = $term->getlflag();
254 .Vb 2
255 \&    $echo     = ECHO | ECHOK | ICANON;
256 \&    $noecho   = $oterm & ~$echo;
259 .Vb 5
260 \&    sub cbreak {
261 \&        $term->setlflag($noecho);  # ok, so i don't want echo either
262 \&        $term->setcc(VTIME, 1);
263 \&        $term->setattr($fd_stdin, TCSANOW);
264 \&    }
267 .Vb 5
268 \&    sub cooked {
269 \&        $term->setlflag($oterm);
270 \&        $term->setcc(VTIME, 0);
271 \&        $term->setattr($fd_stdin, TCSANOW);
272 \&    }
275 .Vb 7
276 \&    sub readkey {
277 \&        my $key = '';
278 \&        cbreak();
279 \&        sysread(STDIN, $key, 1);
280 \&        cooked();
281 \&        return $key;
282 \&    }
285 .Vb 1
286 \&    END { cooked() }
289 .Vb 1
290 \&    1;
292 .Sh "How do I check whether input is ready on the keyboard?"
293 .IX Subsection "How do I check whether input is ready on the keyboard?"
294 The easiest way to do this is to read a key in nonblocking mode with the
295 Term::ReadKey module from \s-1CPAN\s0, passing it an argument of \-1 to indicate
296 not to block:
298 .Vb 1
299 \&    use Term::ReadKey;
302 .Vb 1
303 \&    ReadMode('cbreak');
306 .Vb 5
307 \&    if (defined ($char = ReadKey(-1)) ) {
308 \&        # input was waiting and it was $char
309 \&    } else {
310 \&        # no input was waiting
311 \&    }
314 .Vb 1
315 \&    ReadMode('normal');                  # restore normal tty settings
317 .Sh "How do I clear the screen?"
318 .IX Subsection "How do I clear the screen?"
319 If you only have do so infrequently, use \f(CW\*(C`system\*(C'\fR:
321 .Vb 1
322 \&    system("clear");
325 If you have to do this a lot, save the clear string
326 so you can print it 100 times without calling a program
327 100 times:
329 .Vb 2
330 \&    $clear_string = `clear`;
331 \&    print $clear_string;
334 If you're planning on doing other screen manipulations, like cursor
335 positions, etc, you might wish to use Term::Cap module:
337 .Vb 3
338 \&    use Term::Cap;
339 \&    $terminal = Term::Cap->Tgetent( {OSPEED => 9600} );
340 \&    $clear_string = $terminal->Tputs('cl');
342 .Sh "How do I get the screen size?"
343 .IX Subsection "How do I get the screen size?"
344 If you have Term::ReadKey module installed from \s-1CPAN\s0,
345 you can use it to fetch the width and height in characters
346 and in pixels:
348 .Vb 2
349 \&    use Term::ReadKey;
350 \&    ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
353 This is more portable than the raw \f(CW\*(C`ioctl\*(C'\fR, but not as
354 illustrative:
356 .Vb 10
357 \&    require 'sys/ioctl.ph';
358 \&    die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
359 \&    open(TTY, "+</dev/tty")                     or die "No tty: $!";
360 \&    unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
361 \&        die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\en", &TIOCGWINSZ;
362 \&    }
363 \&    ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
364 \&    print "(row,col) = ($row,$col)";
365 \&    print "  (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel;
366 \&    print "\en";
368 .Sh "如何向使用者询问密码?"
369 .IX Subsection "How do I ask the user for a password?"
370 (这个问题跟全球资讯网一点关系也没有。如果你要找的是跟 WWW 有关的,那就 看另一份常见问题集吧。)
372 在 perlfunc 中的 \*(L"crypt\*(R" 里面有个范例。首先,将你的终端机设为「无回应」\*(L"no echo\*(R" 模式,然後就用平常的方法将密码读入。你可以用老式的 ioctl() 函数、 POSIX 终端机控制函数(参看 POSIX ,和骆驼书第七章),或是呼叫 stty 程式,这些方法的可携性/移植性程度都不一样。
374 你也可以在大部份系统上使用 CPAN 里的 Term::ReadKey 模组,这个模组较易使用而且理论上也较据可携性/移植性。
376 .Vb 1
377 \&    use Term::ReadKey;
380 .Vb 2
381 \&    ReadMode('noecho');
382 \&    $password = ReadLine(0);
384 .Sh "如何读写串口?"
385 .IX Subsection "How do I read and write the serial port?"
386 这端看你在什麽作业系统上执行你的程式。以 Unix 来说,序列埠可以透过 /dev 目录下的档案来撷取; 而在其他系统上,设备的名称无疑地会不一样。以下是一些在设备互动时可能遭遇的共同问题:
387 .IP "lockfiles" 4
388 .IX Item "lockfiles"
389 你的系统可能会使用锁档来控制多重读写的情况。确定你用的是正确的协定。因为当多个程序同时对一个装置做读取时可能会发生意想不到的情况。
390 .IP "open mode" 4
391 .IX Item "open mode"
392 如果你打算对一个装置同时做读与写的动作,你得将它开到更新的模式( 在 perlfunc 中的 open 里有更详细的解说)。如果你不希望冒着阻挡其他程序读取 这个装置的风险,那就得用 sysopen() 和 Fcntl 模组(标准 perl 的一部分)内 的 \f(CW\*(C`O_RDWR|O_NDELAY|O_NOCTTY\*(C'\fR。在 perlfunc 中的 sysopen 里有对此方法更 详尽的解说。
393 .IP "end of line" 4
394 .IX Item "end of line"
395 有些装置会等着在每行结尾处看到一个 \*(L"\er\*(R",而非 \*(L"\en\*(R"。在某些平台上的 perl, \*(L"\er\*(R"和 \*(L"\en\*(R" 与它们平常(在 Unix 上)所指的 ASCII 值 \*(L"\e015\*(R" 和 \*(L"\e012\*(R" 有 所不同。你也许得直接给定数值,例如用八进位 (\*(L"\e015\*(R")、十六进位 (\*(L"0x0D\*(R"), 或指定控制字元 (\*(L"\ecM\*(R")。
397 .Vb 2
398 \&    print DEV "atv1\e012";       # wrong, for some devices
399 \&    print DEV "atv1\e015";       # right, for some devices
402 尽管对普通的文字档案,一个 \*(L"\en\*(R" 便可解决断行的问题,但目前在不同作业系统 间(Unix、DOS/Win 和 Macintosh),对於断行记号仍无统一标准,而只有用 \*(L"\e015\e012\*(R" 来当成 每行的结尾,然後再视需要去掉输出中不想要的部份。这 个做法尤其常用於 socket输出/输入 与自动刷新 (autoflushing),也是接下来 要讨论的主题。
403 .IP "flushing output" 4
404 .IX Item "flushing output"
405 如果你希望 print() 的时候每个字元都要送到你指定的装置去,那你应自动刷新文件句柄。可以使用 \fIselect()\fR 和 \f(CW$|\fR 变量控制自动刷新,参见 perlvar 中的 "$|" 和 perlfunc 中的 \*(L"select\*(R",或 perlfaq5, ``How do I flush/unbuffer an
406 output filehandle?  Why must I do this?''):
408 .Vb 3
409 \&    $oldh = select(DEV);
410 \&    $| = 1;
411 \&    select($oldh);
414 你也可能看到不使用额外的暂存变数的写法,例如:
416 .Vb 1
417 \&    select((select(DEV), $| = 1)[0]);
420 Or if you don't mind pulling in a few thousand lines
421 of code just because you're afraid of a little $| variable:
423 .Vb 2
424 \&    use IO::Handle;
425 \&    DEV->autoflush(1);
428 As mentioned in the previous item, this still doesn't work when using
429 socket I/O between Unix and Macintosh.  You'll need to hard code your
430 line terminators, in that case.
431 .IP "non-blocking input" 4
432 .IX Item "non-blocking input"
433 如果你正在做一个阻塞的 read() 或 sysread() 动作,则你需要安排一个闹 铃把手或提供一个逾时设定(参看 alarm)。如果你是用非阻挡式的 开档,那麽就要配合非阻挡性的读取,也就是说得用到4 个参数的 select() 来确 定此装置的 输出/入 是否已准备好了(参考 perlfunc 中的 select )。
435 While trying to read from his caller-id box, the notorious Jamie Zawinski
436 <jwz@netscape.com>, after much gnashing of teeth and fighting with sysread,
437 sysopen, \s-1POSIX\s0's tcgetattr business, and various other functions that
438 go bump in the night, finally came up with this:
440 .Vb 13
441 \&    sub open_modem {
442 \&        use IPC::Open2;
443 \&        my $stty = `/bin/stty -g`;
444 \&        open2( \e*MODEM_IN, \e*MODEM_OUT, "cu -l$modem_device -s2400 2>&1");
445 \&        # starting cu hoses /dev/tty's stty settings, even when it has
446 \&        # been opened on a pipe...
447 \&        system("/bin/stty $stty");
448 \&        $_ = <MODEM_IN>;
449 \&        chomp;
450 \&        if ( !m/^Connected/ ) {
451 \&            print STDERR "$0: cu printed `$_' instead of `Connected'\en";
452 \&        }
453 \&    }
455 .Sh "如何解码加密的口令文件?"
456 .IX Subsection "How do I decode encrypted password files?"
457 花大把大把的钱去买破解专用的硬体,这会让你成为焦点话题。
459 说正经的,如果是碰到 Unix 密码档的话就不行 - Unix 密码系统用的是单向的加 密函数。像 Crack 之类的程式可以暴力地(并聪明地)试着猜出密码,但无法 (也不能)保证速战速决。
461 如果你耽心的是使用者选取不良的密码,你应该在使用者换密码时主动审核(例如说修改 \fIpasswd\fR\|(1) 程式加入这个功能)。
462 .Sh "如何在后台开启进程?"
463 .IX Subsection "How do I start a process in the background?"
464 Several modules can start other processes that do not block
465 your Perl program.  You can use IPC::Open3, Parallel::Jobs,
466 IPC::Run, and some of the \s-1POE\s0 modules.  See \s-1CPAN\s0 for more
467 details.
469 你可以使用:
471 .Vb 1
472 \&    system("cmd &")
475 或是用 fork,像 perlfunc 中的 fork 里写的(在 perlipc 里有更进一步的 范例)。如果你在 Unix 类的系统上的话,请注意以下几件事情:
476 .IP "\s-1STDIN\s0, \s-1STDOUT\s0, and \s-1STDERR\s0 are shared" 4
477 .IX Item "STDIN, STDOUT, 和 STDERR 是共享的"
478 主程序和背景程序(即「子」程序)共用同一个 STDIN、STDOUT 和 STDERR 档案 把手。如果两个程序想同时去读、写同一个档案把手,就可能有怪事会发生。你也 许应该替子程序关闭或重新开启这些把手。你可以用开启一个管道 (pipe) 的方法 避免这些问题(参看 open)但是在某些系统上这样做会强迫子程序 必须比父程序早死。
479 .IP "信号" 4
480 .IX Item "Signals"
481 SIGCHLD、可能还有 SIGPIPE 这两个讯号要抓到。当背景程序执行完成後就会送出 SIGCHLD 讯号。而当你写入一个子程序已经关闭的档案把手时就会收到 SIGPIPE 讯号(一个未抓住的 SIGPIPE 可能导致你的程式无声无息地死去)。用 system("cmd&") 的话不会有这样的问题。
482 .IP "僵尸进程" 4
483 .IX Item "Zombies"
484 你得做准备,在子程序结束时「收成」它:
486 .Vb 1
487 \&    $SIG{CHLD} = sub { wait };
490 .Vb 1
491 \&    $SIG{CHLD} = 'IGNORE';
494 You can also use a double fork. You immediately \fIwait()\fR for your
495 first child, and the init daemon will \fIwait()\fR for your grandchild once
496 it exits.
498 .Vb 8
499 \&        unless ($pid = fork) {
500 \&                unless (fork) {
501 \&            exec "what you really wanna do";
502 \&            die "exec failed!";
503 \&                }
504 \&        exit 0;
505 \&        }
506 \&    waitpid($pid,0);
509 在 Signals 有范例程式教你怎麽做。用 system("prog &") 的 话不会有僵 程序的问题。
510 .Sh "如何截获控制字符/信号?"
511 .IX Subsection "How do I trap control characters/signals?"
512 你并不能真的 ``捕捉'' 一个控制字元。而是控制字元产生一个讯号让你捕捉。关於讯号的资料可以在 Signals 以及骆驼书第六章里找到。
514 要小心的是,大多 C 程式库无法重新进入 [re-entrant]。因此当你要尝试着在一 个处理器里做 print() 动作,而这个处理器是由另一个stdio 的动作所叫出来的 话,你的内部结构可能会处於失调状态,而程式可能会丢出记忆核心 (dump core)。 有的时候你可以用 syswrite() 取代 print() 以避免这个状况。
516 除非你极为小心,否则在一个讯号处理器中,唯一安全可做的是:设定一个变数後离开。而在第一个情况下,你在设定变数的时候应确定 malloc() 不会被叫出来 (譬如,设定一个已经有值的变数)。
518 例如:
520 .Vb 5
521 \&    $Interrupted = 0;   # 确定它有个值
522 \&    $SIG{INT} = sub {
523 \&        $Interrupted++;
524 \&        syswrite(STDERR, "ouch\en", 5);
525 \&    }
528 然而,因为系统呼叫会自己重新启动,你将会发现如果你用的是「慢的」呼叫,像 < FH>、read()、connect() 或 wait(),那麽将它们停下的唯一办法是使 用「跳远」的方式跳出来;也就是产生一个例外讯号。参看在 Signals 里对阻挡性 flock() 的逾时处理器的说明,或骆驼书第六 章。
529 .Sh "在 Unix 系统中如何修改 shadow 文件?"
530 .IX Subsection "How do I modify the shadow password file on a Unix system?"
531 如果你的 perl 安装正确的话,在 perlfunc 里描述的 getpw*() 函数应该就能够读取隐式密码档了(只有读取权)。要更动该档案内容,做一个新的密码档(这个档案的格式因系统而异,请看 passwd(5) )然後用 pwd_mkdb(8)(参考 pwd_mkdb(5))来安装新的密码档。
532 .Sh "如何设置时间和日期?"
533 .IX Subsection "How do I set the time and date?"
534 假设你有足够的权限,你应该可以用 date(1) 程式来设定系统的时间与日期。 (但没有针对个别程序修改时间日期的方法)这机制在 Unix、MS-DOS、Windows 和 NT 下都能用;VMS 下则要用 set time 。
536 然而,如果你只是要更动你的时区,只消设定一个环境变数即可:
538 .Vb 3
539 \&    $ENV{TZ} = "MST7MDT";                  # unixish
540 \&    $ENV{'SYS$TIMEZONE_DIFFERENTIAL'}="-5" # vms
541 \&    system "trn comp.lang.perl.misc";
543 .Sh "如何 sleep() 或 alarm() 少于一秒的时间?"
544 .IX Subsection "How can I sleep() or alarm() for under a second?"
545 如果你要比 sleep() 所提供的最小单位一秒更精细的话,最简单的方法就是用 select 里面写的 select() 函数。试一试 Time::HiRes 和 BSD::Itimer 模块 (可以从 CPAN 下载,从 Perl 5.8 开始 Time::HiRes 成为标准发行的一部分).
546 .Sh "如何测度少于一秒的时间?"
547 .IX Subsection "How can I measure time under a second?"
548 一般来说,你可能做不到。 Time::HiRes 模组(CPAN 有,从 Perl 5.8 开始成为标准发行的一部分)在某些系统上能达到此 功能。
550 总之,你可能做不到。但是如果你的 Perl 支援 syscall() 函数并支援类似 gettimeofday(2) 的系统呼叫,你也许可以这麽做:
552 .Vb 1
553 \&    require 'sys/syscall.ph';
556 .Vb 1
557 \&    $TIMEVAL_T = "LL";
560 .Vb 1
561 \&    $done = $start = pack($TIMEVAL_T, ());
564 .Vb 2
565 \&    syscall(&SYS_gettimeofday, $start, 0) != -1
566 \&               or die "gettimeofday: $!";
569 .Vb 3
570 \&       ##########################
571 \&       # DO YOUR OPERATION HERE #
572 \&       ##########################
575 .Vb 2
576 \&    syscall( &SYS_gettimeofday, $done, 0) != -1
577 \&           or die "gettimeofday: $!";
580 .Vb 2
581 \&    @start = unpack($TIMEVAL_T, $start);
582 \&    @done  = unpack($TIMEVAL_T, $done);
585 .Vb 2
586 \&    # fix microseconds
587 \&    for ($done[1], $start[1]) { $_ /= 1_000_000 }
590 .Vb 3
591 \&    $delta_time = sprintf "%.4f", ($done[0]  + $done[1]  )
592 \&                                            -
593 \&                                 ($start[0] + $start[1] );
595 .Sh "如何做 atexit()或 setjmp()/longjmp()的动作?(异常处理)"
596 .IX Subsection "How can I do an atexit() or setjmp()/longjmp()? (Exception handling)"
597 第五版的 Perl 增加了 END 区块,可以用来模拟 atexit()的效果。当程式或执行 绪(thread) 终了时就会去呼叫该包装的 END 区块(参考 perlmod 文件)。
599 For example, you can use this to make sure your filter program
600 managed to finish its output without filling up the disk:
602 .Vb 3
603 \&    END {
604 \&        close(STDOUT) || die "stdout close failed: $!";
605 \&    }
608 如果当程式被没有抓到的讯号终结了,END 区块就不会被呼叫到,所以当你用 END 时应再加上
610 .Vb 1
611 \&        use sigtrap qw(die normal-signals);
614 Perl 的例外处理机制就是它的 eval() 运算子。你可以把 eval() 当做 setjmp 而die()当做 longjmp 来使用。更详细的说明请参考 Signals 和 Camel书第六章里关於讯号的那段,尤其是描述有关 flock() 的逾时处理器那段。
616 如果你只对例外处理的部分有兴趣,试试 exceptions.pl 程式库(包含在标准 perl里)。
618 如果你要的是 atexit() 语法(以及 rmexit()),试试 CPAN 里的 AtExit 模组。
619 .ie n .Sh "为何我的 sockets程式在 System V (Solaris)系统下不能用?「不支持的协议」这个错误讯息又是什麽意思?"
620 .el .Sh "为何我的 sockets程式在 System V (Solaris)系统下不能用?「不支持的协议」这个错误讯息又是什麽意思?"
621 .IX Subsection "Why doesn't my sockets program work under System V (Solaris)?  What does the error message Protocol not supported mean?"
622 有些 Sys-V 根底的系统,特别像 Solaris 2.X,已重新将一些标准的 socket常数 定义过了。由於这些常数在各种架构下都是定值,所以在 perl程式码中常被人写 死在里面。处理此问题的适当方式 是用 ``use Socket'' 来取得正确的值。
624 须注意尽管 SunOS 和 Solaris 在二进位执行档上相容,这些值是相异的。自己去 想为什麽吧。
625 .Sh "如何从 Perl里呼叫系统中独特的 C函数?"
626 .IX Subsection "How can I call my system's unique C functions from Perl?"
627 通常是写个外部的模组来处理 - 参看「我要如何学到将 C 与 Perl 连结在一起? [h2xs, xsubpp]」 这问题的答案。然而,如果此函数是个系统呼叫,而你的系统 有支援 syscall(),那麽可以用 syscall 函数(说明在 perlfunc 里)。
629 切记先查查看你的 perl 版本中所附的模组以及 CPAN 里的模组,因为也许某人已 经写了个这样的模组。
630 On Windows, try Win32::API.  On Macs, try Mac::Carbon.  If no module
631 has an interface to the C function, you can inline a bit of C in your
632 Perl source with Inline::C.
633 .Sh "在哪里可以找引入档来做 ioctl()或 syscall()?"
634 .IX Subsection "Where do I get the include files to do ioctl() or syscall()?"
635 以前这些档案会由标准 perl 发行中所附的 h2ph 工具来产生。这个程式将 C 标 头档案里的 cpp(1)指令转换成内含副程式定义的档案,像 &SYS_getitimer,你可 以把它当做函数的参数。这样做并不怎麽完美,但通常可达成任务。简单的像 errno.h 、syscall.h 和socket.h 这些档案都没问题,但像 ioctl.h 这种较难的档案总是需要人工编辑。以下是安装 *.ph 档案的步骤:
637 .Vb 3
638 \&    1.  成为超级用户
639 \&    2.  cd /usr/include
640 \&    3.  h2ph *.h */*.h
643 如果你的系统支援动态载入,那麽为了可移植性、而且合理的做法是使用 h2xs(也 是 perl的标准配备)。这个工具将 C 标头档案转换成 Perl 的衍伸档案 (extensions)。 h2xs 的入门要看 perlxstut 。
645 如果你的系统不支援动态载入,你可能仍应使用 h2xs。参看 perlxstut 和 MakeMaker (简单来说,就是用 make perl 、而非 make 来重 建一份使用新的静态连结的 perl)。
646 .Sh "为何 setuid perl程式会抱怨关於系统核心的问题?"
647 .IX Subsection "Why do setuid perl scripts complain about kernel problems?"
648 有些作业系统的核心有臭虫使得 setuid 程式在先天上就不安全。Perl提供你一些方法(在 perlsec 里有写)可跳过这些系统的缺陷。
649 .Sh "如何打开对某程式既输入又输出的管道 (pipe)?"
650 .IX Subsection "How can I open a pipe both to and from a command?"
651 IPC::Open2 模组(perl 的标准配件)是个好用的方法,它在内部是藉着pipe()、 fork() 和 exec() 来完成此工作。不过切记要读它文件里关於锁死的警告 ( 参见 IPC::Open2 )。参见 perlipc 中的 \*(L"Bidirectional Communication with Another Process\*(R" 和
652 \&\*(L"Bidirectional Communication with Yourself\*(R"
654 You may also use the IPC::Open3 module (part of the standard perl
655 distribution), but be warned that it has a different order of
656 arguments from IPC::Open2 (see IPC::Open3).
657 .Sh "为何用 system()却得不到一个指令的输出呢?"
658 .IX Subsection "Why can't I get the output of a command with system()?"
659 你把 system() 和反向引号 (``) 的用法搞混了。 system() 会执行一个指令然後 传回指令结束时的状况资讯(以一个 16 进位值表示:低位元是程序中止所收到的 讯号,高位元才是真正离开时的传回值)。反向引号 (``) 执行一个指令并且把它 所送出的东西送到 STDOUT。
661 .Vb 2
662 \&    $exit_status   = system("mail-users");
663 \&    $output_string = `ls`;
665 .Sh "如何捕捉外部指令的 STDERR?"
666 .IX Subsection "How can I capture STDERR from an external command?"
667 有叁种基本方式执行外部指令:
669 .Vb 3
670 \&    system $cmd;                # 使用 system()
671 \&    $output = `$cmd`;           # 使用 backticks (``)
672 \&    open (PIPE, "cmd |");       # 使用 open()
675 在 system() 下,STDOUT 和 STDERR 都会输出到和 script 本身的 STDOUT, STDERR相同的出处,除非指令本身将它们导向它处。反向引号和 open() 则 只 读取指令的 STDOUT 部份。
677 你也可以使用 IPC::Open3 模组.  Benjamin
678 Goldberg provides some sample code:
680 To capture a program's \s-1STDOUT\s0, but discard its \s-1STDERR:\s0
682 .Vb 7
683 \&    use IPC::Open3;
684 \&    use File::Spec;
685 \&    use Symbol qw(gensym);
686 \&    open(NULL, ">", File::Spec->devnull);
687 \&    my $pid = open3(gensym, \e*PH, ">&NULL", "cmd");
688 \&    while( <PH> ) { }
689 \&    waitpid($pid, 0);
692 To capture a program's \s-1STDERR\s0, but discard its \s-1STDOUT:\s0
694 .Vb 7
695 \&    use IPC::Open3;
696 \&    use File::Spec;
697 \&    use Symbol qw(gensym);
698 \&    open(NULL, ">", File::Spec->devnull);
699 \&    my $pid = open3(gensym, ">&NULL", \e*PH, "cmd");
700 \&    while( <PH> ) { }
701 \&    waitpid($pid, 0);
704 To capture a program's \s-1STDERR\s0, and let its \s-1STDOUT\s0 go to our own \s-1STDERR:\s0
706 .Vb 5
707 \&    use IPC::Open3;
708 \&    use Symbol qw(gensym);
709 \&    my $pid = open3(gensym, ">&STDERR", \e*PH, "cmd");
710 \&    while( <PH> ) { }
711 \&    waitpid($pid, 0);
714 To read both a command's \s-1STDOUT\s0 and its \s-1STDERR\s0 separately, you can
715 redirect them to temp files, let the command run, then read the temp
716 files:
718 .Vb 10
719 \&    use IPC::Open3;
720 \&    use Symbol qw(gensym);
721 \&    use IO::File;
722 \&    local *CATCHOUT = IO::File->new_tempfile;
723 \&    local *CATCHERR = IO::File->new_tempfile;
724 \&    my $pid = open3(gensym, ">&CATCHOUT", ">&CATCHERR", "cmd");
725 \&    waitpid($pid, 0);
726 \&    seek $_, 0, 0 for \e*CATCHOUT, \e*CATCHERR;
727 \&    while( <CATCHOUT> ) {}
728 \&    while( <CATCHERR> ) {}
731 But there's no real need for *both* to be tempfiles... the following
732 should work just as well, without deadlocking:
734 .Vb 9
735 \&    use IPC::Open3;
736 \&    use Symbol qw(gensym);
737 \&    use IO::File;
738 \&    local *CATCHERR = IO::File->new_tempfile;
739 \&    my $pid = open3(gensym, \e*CATCHOUT, ">&CATCHERR", "cmd");
740 \&    while( <CATCHOUT> ) {}
741 \&    waitpid($pid, 0);
742 \&    seek CATCHERR, 0, 0;
743 \&    while( <CATCHERR> ) {}
746 And it'll be faster, too, since we can begin processing the program's
747 stdout immediately, rather than waiting for the program to finish.
749 在上述方法中,你可以在呼叫前更改文件描述符 (file descriptor) 名称:
751 .Vb 2
752 \&    open(STDOUT, ">logfile");
753 \&    system("ls");
756 或者使用 Bourne shell 的文件描述符重导功能:
758 .Vb 2
759 \&    $output = `$cmd 2>some_file`;
760 \&    open (PIPE, "cmd 2>some_file |");
763 也可以用档案描述元重导功能将 STDERR 复制为 STDOUT:
765 .Vb 2
766 \&    $output = `$cmd 2>&1`;
767 \&    open (PIPE, "cmd 2>&1 |");
770 注意你 不能 光是将 STDERR 开成 STDOUT 的复制,而不呼叫 shell来做这个 重导的工作。这样是不行的:
772 .Vb 2
773 \&    open(STDERR, ">&STDOUT");
774 \&    $alloutput = `cmd args`;  # stderr still escapes
777 失败的原因是,open() 让 STDERR 在呼叫 open() 时往 STDOUT的方向走。然後反 向引号让 STDOUT的内容跑到一个字串变数里,但是没有改变 STDERR 的去向(它 仍然往旧的 STDOUT那里跑)。
779 注意,在反向引号里你 必须 使用 Bourne shell (sh(1)) 重导的语法而非 csh(1)的!至於为何 Perl 的 system()、反向引号和开管道都用 Bourne shell语法的原因,可在下址找到:\*(L"Far More Than You Ever Wanted To Know\*(R", http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz .  要同时捕捉一个命令的 \s-1STDERR\s0 和 \s-1STDOUT\s0:
781 .Vb 3
782 \&    $output = `cmd 2>&1`;                       # either with backticks
783 \&    $pid = open(PH, "cmd 2>&1 |");              # or with an open pipe
784 \&    while (<PH>) { }                            #    plus a read
787 To capture a command's \s-1STDOUT\s0 but discard its \s-1STDERR:\s0
789 .Vb 3
790 \&    $output = `cmd 2>/dev/null`;                # either with backticks
791 \&    $pid = open(PH, "cmd 2>/dev/null |");       # or with an open pipe
792 \&    while (<PH>) { }                            #    plus a read
795 To capture a command's \s-1STDERR\s0 but discard its \s-1STDOUT:\s0
797 .Vb 3
798 \&    $output = `cmd 2>&1 1>/dev/null`;           # either with backticks
799 \&    $pid = open(PH, "cmd 2>&1 1>/dev/null |");  # or with an open pipe
800 \&    while (<PH>) { }                            #    plus a read
803 To exchange a command's \s-1STDOUT\s0 and \s-1STDERR\s0 in order to capture the \s-1STDERR\s0
804 but leave its \s-1STDOUT\s0 to come out our old \s-1STDERR:\s0
806 .Vb 3
807 \&    $output = `cmd 3>&1 1>&2 2>&3 3>&-`;        # either with backticks
808 \&    $pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&-|");# or with an open pipe
809 \&    while (<PH>) { }                            #    plus a read
812 To read both a command's \s-1STDOUT\s0 and its \s-1STDERR\s0 separately, it's easiest
813 and safest to redirect them separately to files, and then read from those
814 files when the program is done:
816 .Vb 1
817 \&    system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr");
820 Ordering is important in all these examples.  That's because the shell
821 processes file descriptor redirections in strictly left to right order.
823 .Vb 2
824 \&    system("prog args 1>tmpfile 2>&1");
825 \&    system("prog args 2>&1 1>tmpfile");
828 The first command sends both standard out and standard error to the
829 temporary file.  The second command sends only the old standard output
830 there, and the old standard error shows up on the old standard out.
831 .Sh "为何当管道开启失败时 open()不会传回错误讯息?"
832 .IX Subsection "Why doesn't open() return an error when a pipe open fails?"
833 If the second argument to a piped \fIopen()\fR contains shell
834 metacharacters, perl \fIfork()\fRs, then \fIexec()\fRs a shell to decode the
835 metacharacters and eventually run the desired program.  If the program
836 couldn't be run, it's the shell that gets the message, not Perl. All
837 your Perl program can find out is whether the shell itself could be
838 successfully started.  You can still capture the shell's \s-1STDERR\s0 and
839 check it for error messages.  See \*(L"How can I capture \s-1STDERR\s0 from an external command?\*(R" elsewhere in this document, or use the
840 IPC::Open3 module.
842 If there are no shell metacharacters in the argument of \fIopen()\fR, Perl
843 runs the command directly, without using the shell, and can correctly
844 report whether the command started.
845 .Sh "在忽略返回值的上下文里使用反向引号有何不对?"
846 .IX Subsection "What's wrong with using backticks in a void context?"
847 严格说起来,没啥不对。但从程式写作严谨与否来说,这样无法写出较易维护的程式码。Perl 有多种方法可以运行外部命令。反引号只是其中一个;它收集命令的输出,在程序中加以应用。 \f(CW\*(C`system\*(C'\fR 函数是另一个,它不这样做
849 Writing backticks in your program sends a clear message to the readers
850 of your code that you wanted to collect the output of the command.
851 Why send a clear message that isn't true?
853 再看看下列这一行:
855 .Vb 1
856 \&    `cat /etc/termcap`;
859 你还没有指定输出,所以它会浪费记忆体(就那麽一下子)。另外你也忘了检查 \f(CW$?\fR 看看程式是否正确的执行。即使你写成
861 .Vb 1
862 \&    print `cat /etc/termcap`;
865 但在大部份情况下,这本来可以、而且也应该写成
867 .Vb 2
868 \&    system("cat /etc/termcap") == 0
869 \&        or die "cat program failed!";
872 这样可快速地得到输出(一产生出来就会得到,不用等到最後),并且检查传回值。
874 \&\fIsystem()\fR 同时具有直接决定是否先做 shell 万用字元 (wildcard)处理的功能, 反向引号就不行。
875 .Sh "如何不经过 shell处理来呼叫反向引号?"
876 .IX Subsection "How can I call backticks without shell processing?"
877 这需要些技巧。不能写成这样:
879 .Vb 1
880 \&    @ok = `grep @opts '$search_string' @filenames`;
883 在 Perl 5.8.0 中,你可以使用有多个参数的 \fIopen()\fR。类似 \fIsystem()\fR 和 \fIexec()\fR 的列表形式,不会进行 shell 转义。
885 .Vb 3
886 \&   open( GREP, "-|", 'grep', @opts, $search_string, @filenames );
887 \&   chomp(@ok = <GREP>);
888 \&   close GREP;
891 也可以这样:
893 .Vb 10
894 \&    my @ok = ();
895 \&    if (open(GREP, "-|")) {
896 \&        while (<GREP>) {
897 \&            chomp;
898 \&            push(@ok, $_);
899 \&        }
900 \&        close GREP;
901 \&    } else {
902 \&        exec 'grep', @opts, $search_string, @filenames;
903 \&    }
906 一如 system(),当你 exec() 一个序列时不会有 shell 解译的情况发生。更多示例可以从 perlipc 的 \*(L"Safe Pipe Opens\*(R" 中找到。
908 Note that if you're use Microsoft, no solution to this vexing issue
909 is even possible.  Even if Perl were to emulate \fIfork()\fR, you'd still
910 be stuck, because Microsoft does not have a argc/argv\-style \s-1API\s0.
911 .Sh "为何给了 EOF(Unix上是 ^D,MS-DOS上是 ^Z)後我的程式就不能从 STDIN 读取东西了呢?"
912 .IX Subsection "Why can't my script read from STDIN after I gave it EOF (^D on Unix, ^Z on MS-DOS)?"
913 因为某些 stdio 的 set error 和 eof 旗标需要清除。你可以用 POSIX 模组里定 义的clearerr()。这是在技术上正确的解决之道。还有一些较不保险的方法:
914 .IP "1" 4
915 .IX Item "1"
916 试着保存搜寻指标然後去找它,例如:
918 .Vb 2
919 \&    $where = tell(LOG);
920 \&    seek(LOG, $where, 0);
922 .IP "2" 4
923 .IX Item "2"
924 如果那样行不通,试着去 seek() 档案的另一部份然後再找回来。
925 .IP "3" 4
926 .IX Item "3"
927 如果还是行不通,试着 seek() 档案另一个相异的的部份,读点东西,再回去找。
928 .IP "4" 4
929 .IX Item "4"
930 如果依然不行,放弃使用 stdio 改用 sysread。
931 .Sh "如何把 shell程式转成 perl?"
932 .IX Subsection "How can I convert my shell script to perl?"
933 学习 Perl 然後重写。说真的,没有简单的转换方式。用 shell 做起来很笨的工 作可以用 Perl 很轻松的做到,而就是这些麻烦之处使得 shell->perl 转换程式 非常不可能写得出来。在重新撰写程式的过程里,你会认清自己真正要做的工作为 何,也希望能够跳脱 shell 的管线资料流机制 [pipeline datastream paradigm], 这东西虽对某些事情很方便,但也常造成低效率。
934 .Sh "perl能处理 telnet或 ftp 会话吗?"
935 .IX Subsection "Can I use perl to run a telnet or ftp session?"
936 试试 Net::FTP、TCP::Client 和 NET::Telnet 模组(CPAN 有)。 http://www.perl.com/CPAN/scripts/netstuff/telnet.emul.shar 也有助於模拟 telnet 协定,但是 Net::Telnet 可能较容易使用。
938 如果你所要做的只是假装 telnet 但又不要起始 telnet 时的沟通程序,那麽以下这个标准的双程序方式就可以满足你的需要了:
940 .Vb 12
941 \&    use IO::Socket;             # new in 5.004
942 \&    $handle = IO::Socket::INET->new('www.perl.com:80')
943 \&            || die "can't connect to port 80 on www.perl.com: $!";
944 \&    $handle->autoflush(1);
945 \&    if (fork()) {               # XXX: undef means failure
946 \&        select($handle);
947 \&        print while <STDIN>;    # everything from stdin to socket
948 \&    } else {
949 \&        print while <$handle>;  # everything from socket to stdout
950 \&    }
951 \&    close $handle;
952 \&    exit;
954 .Sh "如何在 Perl里达到 Expect的功能?"
955 .IX Subsection "How can I write expect in Perl?"
956 很久很久以前,有个叫做 chat2.pl 的程式库(perl 标准配备之一),但一直没 真正完工。如果遇到它的话,不要去用它。现在,你的最佳选择就是从 CPAN 来的 Expect 模块,同时它需要 CPAN 的另两个模块, IO::Pty 和 IO::Stty.
957 .ie n .Sh "有没有可能将 perl的指令列隐藏起来,以躲避像 "ps"之类的程式?"
958 .el .Sh "有没有可能将 perl的指令列隐藏起来,以躲避像 ``ps''之类的程式?"
959 .IX Subsection "Is there a way to hide perl's command line from programs such as ps?"
960 首先要注意的是,如果你的目的是为了安全(例如避免人们偷看到密码),那你应该重写你的程式,把重要的资讯从参数中剔除。光是隐藏起来不会让你的程式变得完全安全。
962 如要真的把看得见的指令列改掉,你可以设定 $0 这个变数值,如同 perlvar 里写的。但这方法并非各种作业系统都适用。像 sendmail之类的背景程式 (daemons) 就将它们的状态放在那儿:
964 .Vb 1
965 \&    $0 = "orcus [accepting connections]";
967 .Sh "我在 perl script里 {更动目录,更改我的使用环境}。为何这些改变在程式执行完後就消失了呢?如何让我做的修改显露出来?"
968 .IX Subsection "I {changed directory, modified my environment} in a perl script.  How come the change disappeared when I exited the script?  How do I get my changes to be visible?"
969 .IP "Unix" 4
970 .IX Item "Unix"
971 严格的说起来,这是做不到的-一个 script 的执行是从启动它的 shell 生出一 个不同的程序来执行。这个程序的任何变动不会反映到它的父程序,只会反映到更 改之後它自己创造出来的子程序。有个 shell 魔术可以让你藉着在 shell 里 eval()你 script 的输出来装出这种效果,在 comp.unix.questions FAQ 里有详 细内容。
972 .Sh "如何关闭一个程序的文件句柄而不用等它完成呢?"
973 .IX Subsection "How do I close a process's filehandle without waiting for it to complete?"
974 假设你的系统支援这种功能,那就只要送个适当的讯号给此程序(参看 kill)。通常是先送一个 TERM 讯号,等一下下,然後再送个 KILL 讯号去终结它。
975 .Sh "如何 fork 一个守护进程?"
976 .IX Subsection "How do I fork a daemon process?"
977 如果你所指的是离线的程序(未与 tty 连线者),那下列的程序据说在大部份的 Unix系统都能用。非 Unix 系统的使用者应该检查 Your_OS::Process 模组看看有 没有其他的解决方案。
978 .IP "\(bu" 4
979 打开 /dev/tty 然後对它用 TIOCNOTTY ioctl。请参考 tty(4) 。更好的办法,你可以只用 \fIPOSIX::setsid()\fR 函数,从而不必担心进程组。
980 .IP "\(bu" 4
981 把目录换到 /
982 .IP "\(bu" 4
983 重开 STDIN、STDOUT 和 STDERR 使它们不会与旧的 tty 连接。
984 .IP "\(bu" 4
985 用下列方法把程式丢到后台:
987 .Vb 1
988 \&    fork && exit;
991 The Proc::Daemon module, available from \s-1CPAN\s0, provides a function to
992 perform these actions for you.
993 .Sh "如何知道自己是否在交互地运行?"
994 .IX Subsection "How do I find out if I'm running interactively or not?"
995 问得好。有的时候 \f(CW\*(C`\-t STDIN\*(C'\fRN 和 \f(CW\*(C`\-t STDOUT\*(C'\fR 可以提供线索,有时不行。
997 .Vb 3
998 \&    if (-t STDIN && -t STDOUT) {
999 \&        print "Now what? ";
1000 \&    }
1003 在 POSIX 系统中,你可以用以下方法测试你自己的程序群组与现在控制你终端机 的是否相同:
1005 .Vb 9
1006 \&    use POSIX qw/getpgrp tcgetpgrp/;
1007 \&    open(TTY, "/dev/tty") or die $!;
1008 \&    $tpgrp = tcgetpgrp(fileno(*TTY));
1009 \&    $pgrp = getpgrp();
1010 \&    if ($tpgrp == $pgrp) {
1011 \&        print "foreground\en";
1012 \&    } else {
1013 \&        print "background\en";
1014 \&    }
1016 .Sh "如何为缓慢的事件设置超时?"
1017 .IX Subsection "How do I timeout a slow event?"
1018 如同 Signals 和 Camel 书第六章里所描述的,用 alarm() 函数, 或许再配合上一个讯号处理器。你也可以改用 CPAN 里更具弹性的 Sys::AlarmCall 模组来做。
1020 The \fIalarm()\fR function is not implemented on all versions of Windows.
1021 Check the documentation for your specific version of Perl.
1022 .Sh "如何设置 CPU 限额?"
1023 .IX Subsection "How do I set CPU limits?"
1024 使用 CPAN 里的 BSD::Resource 模组。
1025 .Sh "如何避免在 Unix 系统中产生僵尸进程?"
1026 .IX Subsection "How do I avoid zombies on a Unix system?"
1027 使用 Signals 里面叫 reaper 的程式码,在接到 SIGCHLD 时会呼 叫wait(),或是用 perlfaq8 中的 \*(L"How do I start a process in the background?\*(R" 里面写的双 fork 技巧。
1028 .Sh "如何使用 SQL 数据库?"
1029 .IX Subsection "How do I use an SQL database?"
1030 The \s-1DBI\s0 module provides an abstract interface to most database
1031 servers and types, including Oracle, \s-1DB2\s0, Sybase, mysql, Postgresql,
1032 \&\s-1ODBC\s0, and flat files.  The \s-1DBI\s0 module accesses each database type
1033 through a database driver, or \s-1DBD\s0.  You can see a complete list of
1034 available drivers on \s-1CPAN:\s0 http://www.cpan.org/modules/by\-module/DBD/ .
1035 You can read more about \s-1DBI\s0 on http://dbi.perl.org .
1037 Other modules provide more specific access: Win32::ODBC, Alzabo, iodbc,
1038 and others found on \s-1CPAN\s0 Search: http://search.cpan.org .
1039 .Sh "如何使 system() 在收到 control-C 时退出?"
1040 .IX Subsection "How do I make a system() exit on control-C?"
1041 做不到。你需要摹仿 system() 呼叫(参看 perlipc 里的范例程式),然後设计一个讯号处理器,让它把 INT 讯号传给子程序。或者可以检测它:
1043 .Vb 2
1044 \&    $rc = system($cmd);
1045 \&    if ($rc & 127) { die "signal death" }
1047 .Sh "如何无阻塞地打开一个文件?"
1048 .IX Subsection "How do I open a file without blocking?"
1049 如果你有幸使用到支援无阻塞读的系统(大部份 Unix 般的系统都有支援), 你只需要用 Fcntl 模组里的 O_NDELAY 或 O_NONBLOCK 旗标,配合 sysopen():
1051 .Vb 3
1052 \&    use Fcntl;
1053 \&    sysopen(FH, "/tmp/somefile", O_WRONLY|O_NDELAY|O_CREAT, 0644)
1054 \&        or die "can't open /tmp/somefile: $!":
1056 .Sh "How do I install a module from \s-1CPAN\s0?"
1057 .IX Subsection "如何从 CPAN 安装模块?"
1058 最简单的方法就是让 CPAN 这个模组替你代劳。这个模组包含在 5.004及以後的版 本中。
1060 .Vb 1
1061 \&    $ perl -MCPAN -e shell
1064 .Vb 2
1065 \&    cpan shell -- CPAN exploration and modules installation (v1.59_54)
1066 \&    ReadLine support enabled
1069 .Vb 1
1070 \&    cpan> install Some::Module
1073 如要手动安装 CPAN 模组,或是任何按规矩发展的 CPAN模组,遵循以下步 骤:
1074 .IP "1" 4
1075 .IX Item "1"
1076 把源代码解压到临时目录
1077 .IP "2" 4
1078 .IX Item "2"
1079 .Vb 1
1080 \&    perl Makefile.PL
1082 .IP "3" 4
1083 .IX Item "3"
1084 .Vb 1
1085 \&    make
1087 .IP "4" 4
1088 .IX Item "4"
1089 .Vb 1
1090 \&    make test
1092 .IP "5" 4
1093 .IX Item "5"
1094 .Vb 1
1095 \&    make install
1098 如果你用的 perl 版本在编译时没有建入动态连结的功能,那你只消把第叁步 (make)换成 make perl 然後你就会得到一个新的 perl 执行档,里头连 有你新加入的延伸。
1100 在 ExtUtils::MakeMaker 里面有更多关於建构模组的细节,并参考下一个问题,require 和 use 的区别是什么?。
1101 .Sh "require 和 use 的区别是什么?"
1102 .IX Subsection "What's the difference between require and use?"
1103 Perl offers several different ways to include code from one file into
1104 another.  Here are the deltas between the various inclusion constructs:
1106 .Vb 3
1107 \&    1)  do $file is like eval `cat $file`, except the former
1108 \&        1.1: searches @INC and updates %INC.
1109 \&        1.2: bequeaths an *unrelated* lexical scope on the eval'ed code.
1112 .Vb 3
1113 \&    2)  require $file is like do $file, except the former
1114 \&        2.1: checks for redundant loading, skipping already loaded files.
1115 \&        2.2: raises an exception on failure to find, compile, or execute $file.
1118 .Vb 3
1119 \&    3)  require Module is like require "Module.pm", except the former
1120 \&        3.1: translates each "::" into your system's directory separator.
1121 \&        3.2: primes the parser to disambiguate class Module as an indirect object.
1124 .Vb 3
1125 \&    4)  use Module is like require Module, except the former
1126 \&        4.1: loads the module at compile time, not run-time.
1127 \&        4.2: imports symbols and semantics from that package to the current one.
1130 In general, you usually want \f(CW\*(C`use\*(C'\fR and a proper Perl module.
1131 .Sh "如何设置我自己的模块/库路径?"
1132 .IX Subsection "How do I keep my own module/library directory?"
1133 当你建构模组时,在产生 Makefiles 时使用 PREFIX 选项:
1135 .Vb 1
1136 \&    perl Makefile.PL PREFIX=/mydir/perl LIB=/mydir/perl/lib
1139 然後在执行用到此 模组/程式库 的程式前先设好 PERL5LIB 环境变数(参考 perlrun ),或是用
1141 .Vb 1
1142 \&    use lib '/mydir/perl/lib';
1145 这样与下面几乎相同
1147 .Vb 3
1148 \&    BEGIN {
1149 \&        unshift(@INC, '/mydir/perl/lib');
1150 \&    }
1153 但 lib 模块检测独立于机器的子目录。参见 Perl 的 lib 模块来获取详细信息。
1154 .Sh "如何将我自己的程序的路径加入到模块/库搜索路径中?"
1155 .IX Subsection "How do I add the directory my program lives in to the module/library search path?"
1156 .Vb 3
1157 \&    use FindBin;
1158 \&    use lib "$FindBin::Bin";
1159 \&    use your_own_modules;
1161 .Sh "如何在运行时将一个目录加入到我的 include 路径 (@INC) 中?"
1162 .IX Subsection "How do I add a directory to my include path (@INC) at runtime?"
1163 以下是我们建议更动引入路径的方法:
1165 .Vb 5
1166 \&    环境变量 PERLLIB 
1167 \&    环境变量 PERL5LIB
1168 \&    perl -Idir 命令行标志
1169 \&    use lib 编用,类似
1170 \&        use lib "$ENV{HOME}/myown_perllib";
1173 後者特别有用,因为它知道与机器相关的架构。lib.pm 机制模组是从 5.002 版开 始包含在 Perl 里面的。
1174 .Sh "什么是 socket.ph,从哪儿可以得到它?"
1175 .IX Subsection "What is socket.ph and where do I get it?"
1176 It's a perl4\-style file defining values for system networking
1177 constants.  Sometimes it is built using h2ph when Perl is installed,
1178 but other times it is not.  Modern programs \f(CW\*(C`use Socket;\*(C'\fR instead.
1179 .SH "AUTHOR AND COPYRIGHT"
1180 .IX Header "AUTHOR AND COPYRIGHT"
1181 Copyright (c) 1997\-2003 Tom Christiansen and Nathan Torkington.
1182 All rights reserved.
1184 This documentation is free; you can redistribute it and/or modify it
1185 under the same terms as Perl itself.
1187 Irrespective of its distribution, all code examples in this file
1188 are hereby placed into the public domain.  You are permitted and
1189 encouraged to use this code in your own programs for fun
1190 or for profit as you see fit.  A simple comment in the code giving
1191 credit would be courteous but is not required.
1192 .SH "译者"
1193 .B 陈彦铭,萧百龄,两只老虎工作室