PERLFAQ8 7
PERLFAQ8
NAMEDESCRIPTION æè¿°
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