PERLFAQ8 7

中文man手册

PERLFAQ8

NAME
DESCRIPTION æè¿°
AUTHOR AND COPYRIGHT
è¯è

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 &") ç è¯ä¸ä¼æåµ ç¨åºçé®é¢ã

å¦ä½æªè·æ§å¶å符/ä¿¡å·ï¼

ä½ å¹¶ä¸è½çç ‘‘ææ’’ ä¸ä¸ªæ§å¶ååãèæ¯æ§å¶å- å产çä¸ä¸ªè®¯å·è®©ä½ ææãå³äºè®¯å·çèµæå¯ä»¥å¨ Signals 以åéªé©¼ä¹¦ç¬¬å- ç« éæ¾å°ã

è¦å°å¿çæ¯ï¼å¤§å¤ C ç¨å¼åºæ æ³éæ°è¿å¥ [re-entrant]ãå æ¤å½ä½ è¦å°è¯çå¨ä¸ 个å¤çå¨éå print() å¨ä½ï¼èè¿ä¸ªå¤ç卿¯ç±å¦ä¸ä¸ªstdio çå¨ä½æå«åºæ¥ç è¯ï¼ä½ çåé¨ç»æå¯è½ä¼å¤äºå¤±è°ç¶æï¼èç¨å¼å¯è½ä¼ä¸¢åºè®°å¿æ ¸å¿ (dump core)ã æçæ¶åä½ å¯ä»¥ç¨ syswrite() å代 print() 以é¿åè¿ä¸ªç¶åµã

é¤éä½ æä¸ºå°å¿ï¼å¦åå¨ä¸ä¸ªè®¯å·å¤çå¨ä¸- ï¼å¯ä¸å®å¨å¯åçæ¯ï¼è®¾å®ä¸ä¸ªåæ°å离å¼ãèå¨ç¬¬ä¸ä¸ªæåµä¸ï¼ä½å¨è®¾å®åæ°çæ¶ååºç¡®å® malloc() ä¸ä¼è¢«å«åºæ¥ ï¼è¬å¦ï¼è®¾å®ä¸ä¸ªå·²ç»æå¼çåæ°ï¼ã

ä¾å¦ï¼

$Interrupted = 0; # ç¡®å®å®æä¸ªå¼
$SIG{INT} = sub {
$Interrupted++;
syswrite(STDERR, "ouch\n", 5);
}

ç¶èï¼å ä¸ºç³»ç»å¼å«ä¼èªå·±éæ°å¯å¨ï¼ä½ å°ä¼åç°å¦æä½ ç¨çæ¯ãæ¢çãå¼å«ï¼å < FH>ãread()ãconnect() æ wait()ï¼é£ä¹å°å®ä»¬åä¸çå¯ä¸åæ³æ¯ä½¿ ç¨ãè·³è¿ãçæ¹å¼è·³åºæ¥ï¼ä¹å°±æ¯äº§çä¸ä¸ªä¾å¤è®¯å·ãåçå¨ Signals é坹黿¡æ§ flock() ç龿¶å¤çå¨ç说æï¼æéªé©¼ä¹¦ç¬¬å ç« ã

å¨ 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()çå¨ä½ï¼ï¼å¼å¸¸å¤çï¼

第äºçç Perl å¢å äº END åºåï¼å¯ä»¥ç¨æ¥æ¨¡æ atexit()çææãå½ç¨å¼ææ§è¡ 绪(thread) ç»äºæ¶å°±ä¼å»å¼å«è¯¥åè£ç END åºåï¼åè perlmod æä»¶ï¼ã

For example, you can use this to make sure your filter program managed to finish its output without filling up the disk:

END {
close(STDOUT) ⎪⎪ die "stdout close failed: $!";
}

妿å½ç¨å¼è¢«æ²¡ææå°ç讯å·ç»ç»äºï¼END åºåå°±ä¸ä¼è¢«å¼å«å°ï¼æä»¥å½ä½ ç¨ END æ¶åºåå ä¸

use sigtrap qw(die normal-signals);

Perl çä¾å¤å¤çæºå¶å°±æ¯å®ç eval() è¿ç®åãä½ å¯ä»¥æ eval() å½å setjmp èdie()å½å longjmp æ¥ä½¿ç¨ãæ´è¯¦ç»ç说æè¯·åè Signals å Camel书第å- ç« éå³äºè®¯å·ç飿®µï¼å°¤å¶æ¯æè¿°æå³ flock() ç龿¶å¤çå¨é£æ®µã

妿你åªå¯¹ä¾å¤å¤ççé¨åæå´è¶£ï¼è¯è¯ exceptions.pl ç¨å¼åºï¼åå«å¨æ å perléï¼ã

妿你è¦çæ¯ atexit() è¯æ³ï¼ä»¥å rmexit()ï¼ï¼è¯è¯ CPAN éç AtExit 模ç»ã

ä¸ºä½æç socketsç¨å¼å¨ System V (Solaris)ç³»ç»ä¸ä¸è½ç¨ï¼ã䏿¯æçåè®®ãè¿ä¸ªé误讯æ¯åæ¯ä»ä¹ææï¼

æäº Sys-V æ ¹åºçç³»ç»ï¼ç¹å«å Solaris 2.Xï¼å·²éæ°å°ä¸äºæ åç socketå¸¸æ° å®ä¹è¿äºãç±äºè¿äºå¸¸æ°å¨åç§æ¶æä¸é½æ¯å®å¼ï¼æä»¥å¨ perlç¨å¼ç ä¸å¸¸è¢«äººå æ»å¨éé¢ãå¤çæ¤é®é¢çé彿¹å¼ æ¯ç¨ ‘‘use Socket’’ æ¥å徿£ç¡®çå¼ã

须注æå°½ç®¡ SunOS å Solaris å¨äºè¿ä½æ§è¡æ¡£ä¸ç¸å®¹ï¼è¿äºå¼æ¯ç¸å¼çãèªå·±å» æ³ä¸ºä»ä¹å§ã

å¦ä½ä» Perléå¼å«ç³»ç»ä¸ç¬ç¹ç C彿°ï¼

é常æ¯å个å¤é¨çæ¨¡ç»æ¥å¤ç - åçãæè¦å¦ä½å¦å°å° C ä¸ Perl è¿ç»å¨ä¸èµ·ï¼ [h2xs, xsubpp]ã è¿é®é¢ççæ¡ãç¶èï¼å¦ææ¤å½æ°æ¯ä¸ªç³»ç»å¼å«ï¼èä½ çç³»ç» ææ¯æ´ syscall()ï¼é£ä¹å¯ä»¥ç¨ syscall 彿°ï¼è¯´æå¨ perlfunc éï¼ã

åè®°åæ¥æ¥çä½ ç perl çæ¬ä¸æéçæ¨¡ç»ä»¥å CPAN éçæ¨¡ç»ï¼å ä¸ºä¹è®¸æäººå·² ç»åäºä¸ªè¿æ ·ç模ç»ã On Windows, try Win32::API. On Macs, try Mac::Carbon. If no module has an interface to the C function, you can inline a bit of C in your Perl source with Inline::C.

å¨åªéå¯ä»¥æ¾å¼å¥æ¡£æ¥å ioctl()æ syscall()ï¼

以åè¿äºæ¡£æ¡ä¼ç±æ å perl åè¡ä¸æéç h2ph 工巿¥äº§çãè¿ä¸ªç¨å¼å° C æ  å¤´æ¡£æ¡éç cpp(1)æä»¤è½¬æ¢æåå«å¯ç¨å¼å®ä¹çæ¡£æ¡ï¼å &SYS_getitimerï¼ä½ å¯ 以æå®å½å彿°çåæ°ãè¿æ ·å并䏿ä¹å®ç¾ï¼ä½é常å¯è¾¾æä»»å¡ãç®åçå errno.h ãsyscall.h åsocket.h è¿äºæ¡£æ¡é½æ²¡é®é¢ï¼ä½å ioctl.h è¿ç§è¾é¾çæ¡£æ¡æ»æ¯éè¦äººå·¥ç¼è¾ã以䏿¯å®è£ *.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ç¨å¼ä¼æ±æ¨å³äºç³»ç»æ ¸å¿çé®é¢ï¼

æäºä½ä¸ç³»ç»çæ ¸å¿æèè«ä½¿å¾ setuid ç¨å¼å¨å天ä¸å°±ä¸å®å¨ãPerlæä¾ä½ ä¸äºæ¹æ³ï¼å¨ perlsec éæåï¼å¯è·³è¿è¿äºç³»ç»ç缺é·ã

å¦ä½æå¼å¯¹æç¨å¼æ¢è¾å¥åè¾åºç管é (pipe)ï¼

IPC::Open2 模ç»ï¼perl çæ åéä»¶ï¼æ¯ä¸ªå¥½ç¨çæ¹æ³ï¼å®å¨å鍿¯åçpipe()ã fork() å exec() æ¥å®ææ¤å·¥ä½ãä¸è¿åè®°è¦è¯»å®æä»¶éå³äºéæ»çè¦å ( åè§ IPC::Open2 )ãåè§ perlipc ä¸ç "Bidirectional Communication with Another Process" å "Bidirectional Communication with Yourself"

You may also use the IPC::Open3 module (part of the standard perl distribution), but be warned that it has a different order of arguments from IPC::Open2 (see IPC::Open3).

为ä½ç¨ system()å´å¾ä¸å°ä¸ä¸ªæä»¤çè¾åºå¢ï¼

ä½ æ system() åååå¼å· (‘‘) çç¨æ³ææ··äºã system() 伿§è¡ä¸ä¸ªæä»¤ç¶å ä¼ åæä»¤ç»ææ¶çç¶åµèµè®¯ï¼ä»¥ä¸ä¸ª 16 è¿ä½å¼è¡¨ç¤ºï¼ä½ä½åæ¯ç¨åºä¸æ- ¢ææ¶å°ç 讯å·ï¼é«ä½åææ¯çæ£ç¦»å¼æ¶çä¼ åå¼ï¼ãååå¼å· (‘‘) æ§è¡ä¸ä¸ªæä»¤å¹¶ä¸æå® æéåºçä¸è¥¿éå° STDOUTã

$exit_status = system("mail-users");
$output_string = ‘ls‘;

å¦ä½ææå¤é¨æä»¤ç STDERRï¼

æåç§åºæ¬æ¹å¼æ§è¡å¤é¨æä»¤ï¼

system $cmd; # ä½¿ç¨ system()
$output = ‘$cmd‘; # ä½¿ç¨ backticks (‘‘)
open (PIPE, "cmd ⎪"); # ä½¿ç¨ open()

å¨ system() ä¸ï¼STDOUT å STDERR é½ä¼è¾åºå°å script æ¬èº«ç STDOUT, STDERRç¸åçåºå¤ï¼é¤éæä»¤æ¬èº«å°å®ä»¬å¯¼åå®å¤ãååå¼å·å open() å åª è¯»åæä»¤ç STDOUT é¨ä»½ã

ä½ ä¹å¯ä»¥ä½¿ç¨ IPC::Open3 模ç». Benjamin Goldberg provides some sample code:

To capture a program’s STDOUT , but discard its STDERR:

use IPC::Open3;
use File::Spec;
use Symbol qw(gensym);
open(NULL, ">", File::Spec->devnull);
my $pid = open3(gensym, \*PH, ">&NULL", "cmd");
while( <PH> ) { }
waitpid($pid, 0);

To capture a program’s STDERR , but discard its STDOUT:

use IPC::Open3;
use File::Spec;
use Symbol qw(gensym);
open(NULL, ">", File::Spec->devnull);
my $pid = open3(gensym, ">&NULL", \*PH, "cmd");
while( <PH> ) { }
waitpid($pid, 0);

To capture a program’s STDERR , and let its STDOUT go to our own STDERR:

use IPC::Open3;
use Symbol qw(gensym);
my $pid = open3(gensym, ">&STDERR", \*PH, "cmd");
while( <PH> ) { }
waitpid($pid, 0);

To read both a command’s STDOUT and its STDERR separately, you can redirect them to temp files, let the command run, then read the temp files:

use IPC::Open3;
use Symbol qw(gensym);
use IO::File;
local *CATCHOUT = IO::File->new_tempfile;
local *CATCHERR = IO::File->new_tempfile;
my $pid = open3(gensym, ">&CATCHOUT", ">&CATCHERR", "cmd");
waitpid($pid, 0);
seek $_, 0, 0 for \*CATCHOUT, \*CATCHERR;
while( <CATCHOUT> ) {}
while( <CATCHERR> ) {}

But there’s no real need for *both* to be tempfiles... the following should work just as well, without deadlocking:

use IPC::Open3;
use Symbol qw(gensym);
use IO::File;
local *CATCHERR = IO::File->new_tempfile;
my $pid = open3(gensym, \*CATCHOUT, ">&CATCHERR", "cmd");
while( <CATCHOUT> ) {}
waitpid($pid, 0);
seek CATCHERR, 0, 0;
while( <CATCHERR> ) {}

And it’ll be faster, too, since we can begin processing the program’s stdout immediately, rather than waiting for the program to finish.

å¨ä¸è¿°æ¹æ³ä¸ï¼ä½ å¯ä»¥å¨å¼å«åæ´æ¹æä»¶æè¿°ç¬¦ (file descriptor) åç§°ï¼

open(STDOUT, ">logfile");
system("ls");

æèä½¿ç¨ Bourne shell çæä»¶æè¿°ç¬¦é导åè½ï¼

$output = ‘$cmd 2>some_file‘;
open (PIPE, "cmd 2>some_file ⎪");

ä¹å¯ä»¥ç¨æ¡£æ¡æè¿°åé导åè½å° STDERR å¤å¶ä¸º STDOUTï¼

$output = ‘$cmd 2>&1‘;
open (PIPE, "cmd 2>&1 ⎪");

注æä½  ä¸è½ åæ¯å° STDERR 弿 STDOUT çå¤å¶ï¼èä¸å¼å« shellæ¥åè¿ä¸ª é导çå·¥ä½ãè¿æ ·æ¯ä¸è¡çï¼

open(STDERR, ">&STDOUT");
$alloutput = ‘cmd args‘; # stderr still escapes

失败çåå æ¯ï¼open() 让 STDERR å¨å¼å« open() æ¶å¾ STDOUTçæ¹åèµ°ãç¶åå åå¼å·è®© STDOUTçå容è·å°ä¸ä¸ªå䏲忰éï¼ä½æ¯æ²¡ææ¹å STDERR çå»åï¼å® ä»ç¶å¾æ§ç STDOUTé£éè·ï¼ã

注æï¼å¨ååå¼å·éä½  å¿é¡» ä½¿ç¨ Bourne shell (sh(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()ä¸ä¼ä¼ åé误讯æ¯ï¼

If the second argument to a piped 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)å¤ççåè½ï¼ ååå¼å·å°±ä¸è¡ã

å¦ä½ä¸ç»è¿ shellå¤çæ¥å¼å«ååå¼å·ï¼

è¿éè¦äºæå·§ãä¸è½åæè¿æ ·ï¼

@ok = ‘grep @opts ’$search_string’ @filenames‘;

å¨ Perl 5.8.0 ä¸ï¼ä½ å¯ä»¥ä½¿ç¨æå¤ä¸ªåæ°ç open()ã类似 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 .

为ä½ç»äº EOFï¼Unix䏿¯ ˆDï¼MS-DOS䏿¯ ˆZï¼åæçç¨å¼å°±ä¸è½ä» STDIN 读åä¸è¥¿äºå¢ï¼

å ä¸ºæäº stdio ç set error å eof ææ éè¦æ¸é¤ãä½ å¯ä»¥ç¨ POSIX 模ç»éå® ä¹çclearerr()ãè¿æ¯å¨ææ¯ä¸æ£ç¡®çè§£å³ä¹éãè¿æä¸äºè¾ä¸ä¿é©çæ¹æ³ï¼

1

è¯çä¿åæå¯»ææ ç¶å廿¾å®ï¼ä¾å¦ï¼

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

2

妿飿 ·è¡ä¸éï¼è¯çå» seek() æ¡£æ¡çå¦ä¸é¨ä»½ç¶å忾忥ã

3

å¦æè¿æ¯è¡ä¸éï¼è¯ç seek() æ¡£æ¡å¦ä¸ä¸ªç¸å¼ççé¨ä»½ï¼è¯»ç¹ä¸è¥¿ï¼åå廿¾ã

4

妿ä¾ç¶ä¸è¡ï¼æ¾å¼ä½¿ç¨ stdio æ¹ç¨ sysreadã

å¦ä½æ shellç¨å¼è½¬æ perlï¼

å¦ä¹  Perl ç¶åéåã说ççï¼æ²¡æç®åçè½¬æ¢æ¹å¼ãç¨ shell åèµ·æ¥å¾ç¬¨çå·¥ ä½å¯ä»¥ç¨ Perl å¾è½»æ¾çåå°ï¼èå°±æ¯è¿äºéº»ç¦ä¹å¤ä½¿å¾ shell->perl 转æ¢ç¨å¼ é常ä¸å¯è½åå¾åºæ¥ãå¨éæ°æ°åç¨å¼çè¿ç¨éï¼ä½ ä¼è®¤æ¸èªå·±çæ- £è¦åçå·¥ä½ä¸º ä½ï¼ä¹å¸æè½å¤è·³è± shell çç®¡çº¿èµææµæºå¶ [pipeline datastream paradigm]ï¼ è¿ä¸è¥¿è½å¯¹æäºäºæå¾æ¹ä¾¿ï¼ä½ä¹å¸¸é æä½æçã

perlè½å¤ç telnetæ ftp ä¼è¯åï¼

è¯è¯ 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;

å¦ä½å¨ Perléè¾¾å° Expectçåè½ï¼

å¾ä¹å¾ä¹ä»¥åï¼æä¸ªå«å chat2.pl çç¨å¼åºï¼perl æ åéå¤ä¹ä¸ï¼ï¼ä½ä¸ç´æ²¡ çæ£å®å·¥ã妿éå°å®çè¯ï¼ä¸è¦å»ç¨å®ãç°å¨ï¼ä½ çæä½³éæ©å°±æ¯ä» CPAN æ¥ç Expect 模åï¼åæ¶å®éè¦ CPAN çå¦ä¸¤ä¸ªæ¨¡åï¼ IO::Pty å IO::Stty.

ææ²¡æå¯è½å° perlçæä»¤åéèèµ·æ¥ï¼ä»¥èº²é¿å

é¦åè¦æ³¨æçæ¯ï¼å¦æä½çç®çæ¯ä¸ºäºå®å¨ï¼ä¾å¦é¿å人们å·çå°å¯çï¼ï¼é£ä½åºè¯¥éåä½çç¨å¼ï¼æéè¦çèµè®¯ä»åæ°ä¸- åé¤ã忝éèèµ·æ¥ä¸ä¼è®©ä½ çç¨å¼åå¾å®å¨å®å¨ã

å¦è¦ççæçå¾è§çæä»¤åæ¹æï¼ä½ å¯ä»¥è®¾å® $0 è¿ä¸ªåæ°å¼ï¼å¦å perlvar éåçãä½è¿æ¹æ³å¹¶éåç§ä½ä¸ç³»ç»é½éç¨ãå sendmailä¹ç±»çèæ¯ç¨å¼ (daemons) å°±å°å®ä»¬çç¶ææ¾å¨é£å¿ï¼

$0 = "orcus [accepting connections]";

æå¨ perl scripté {æ´å¨ç®å½ï¼æ´æ¹æç使ç¨ç¯å¢}ã为ä½è¿äºæ¹åå¨ç¨å¼æ§è¡å®åå°±æ¶å¤±äºå¢ï¼å¦ä½è®©æåçä¿®æ¹æ¾é²åºæ¥ï¼
Unix

严格ç说起æ¥ï¼è¿æ¯åä¸å°çï¼ä¸ä¸ª script çæ§è¡æ¯ä»å¯å¨å®ç shell çåºä¸ 个ä¸åçç¨åºæ¥æ§è¡ãè¿ä¸ªç¨åºçä»»ä½åå¨ä¸ä¼åæ å°å®çç¶ç¨åºï¼åªä¼åæ å°æ´ æ¹ä¹åå®èªå·±åé åºæ¥çåç¨åºãæä¸ª shell 鿝å¯ä»¥è®©ä½ åçå¨ shell é eval()ä½  script çè¾åºæ¥è£åºè¿ç§ææï¼å¨ comp.unix.questions FAQ éæè¯¦ ç»å容ã

å¦ä½å³éä¸ä¸ªç¨åºçæä»¶å¥æèä¸ç¨çå®å®æå¢ï¼

å设你çç³»ç»æ¯æ´è¿ç§åè½ï¼é£å°±åªè¦é个éå½ç讯å·ç»æ¤ç¨åºï¼åç killï¼ãé常æ¯åéä¸ä¸ª TERM 讯å·ï¼çä¸ä¸ä¸ï¼ç¶ååé个 KILL 讯å·å»ç»ç»å®ã

å¦ä½ fork ä¸ä¸ªå®æ¤è¿ç¨ï¼

妿你ææçæ¯ç¦»çº¿çç¨åºï¼æªä¸ tty è¿çº¿èï¼ï¼é£ä¸åçç¨åºæ®è¯´å¨å¤§é¨ä»½ç Unixç³»ç»é½è½ç¨ãé Unix ç³»ç»ç使ç¨èåºè¯¥æ£æ¥ Your_OS::Process 模ç»ççæ æ²¡æå¶ä»çè§£å³æ¹æ¡ã

æå¼ /dev/tty ç¶å对å®ç¨ TIOCNOTTY ioctlã请åè tty(4) ãæ´å¥½çåæ³ï¼ä½ å¯ä»¥åªç¨ POSIX::setsid() 彿°ï¼ä»èä¸å¿æå¿è¿ç¨ç»ã

æç®å½æ¢å° /

éå¼ STDINãSTDOUT å STDERR 使å®ä»¬ä¸ä¼ä¸æ§ç tty è¿æ¥ã

ç¨ä¸åæ¹æ³æç¨å¼ä¸¢å°åå°ï¼

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.

å¦ä½è®¾ç½®æèªå·±ç模å/åºè·¯å¾ï¼

å½ä½ å»ºææ¨¡ç»æ¶ï¼å¨äº§ç Makefiles æ¶ä½¿ç¨ PREFIX é项ï¼

perl Makefile.PL PREFIX=/mydir/perl LIB=/mydir/perl/lib

ç¶å卿§è¡ç¨å°æ¤ 模ç»ï¼ç¨å¼åº çç¨å¼åå设好 PERL5LIB ç¯å¢åæ°ï¼åè perlrun ï¼ï¼ææ¯ç¨

use lib ’/mydir/perl/lib’;

è¿æ ·ä¸ä¸é¢å ä¹ç¸å

BEGIN {
unshift(@INC, ’/mydir/perl/lib’);
}

ä½ lib æ¨¡åæ£æµç¬ç«äºæºå¨çåç®å½ãåè§ Perl ç lib æ¨¡åæ¥è·å详ç»ä¿¡æ¯ã

å¦ä½å°æèªå·±çç¨åºçè·¯å¾å å¥å°æ¨¡å/åºæç´¢è·¯å¾ä¸ï¼

use FindBin;
use lib "$FindBin::Bin";
use your_own_modules;

å¦ä½å¨è¿è¡æ¶å°ä¸ä¸ªç®å½å å¥å°æç include è·¯å¾ (@INC) ä¸ï¼

以䏿¯æä»¬å»ºè®®æ´å¨å¼å¥è·¯å¾çæ¹æ³ï¼

ç¯å¢åé PERLLIB
ç¯å¢åé PERL5LIB
perl -Idir å½ä»¤è¡æ å¿
use lib ç¼ç¨ï¼ç±»ä¼¼
use lib "$ENV{HOME}/myown_perllib";

åèç¹å«æç¨ï¼å ä¸ºå®ç¥é䏿ºå¨ç¸å³çæ¶æãlib.pm æºå¶æ¨¡ç»æ¯ä» 5.002 çå¼ å§åå«å¨ Perl éé¢çã

ä»ä¹æ¯ socket.phï¼ä»åªå¿å¯ä»¥å¾å°å®ï¼

It’s a perl4-style file defining values for system networking constants. Sometimes it is built using h2ph when Perl is installed, but other times it is not. Modern programs "use Socket;" instead.

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.

è¯è

é彦éï¼è§ç¾é¾ï¼ä¸¤åªèèå·¥ä½å®¤

è·

æ¬é¡µé¢ä¸æçç±ä¸æ man æå页计åæä¾ã
䏿 man æå页计åï¼https://github.com/man-pages-zh/manpages-zh