perl入门基本读物_第1页
perl入门基本读物_第2页
perl入门基本读物_第3页
perl入门基本读物_第4页
perl入门基本读物_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

-.z我的评价:本书是perl的经典入门书籍,介绍了perl中最根本的概念和语法,是perl入门的好书,我向所有想了解或学习perl语言的朋友推荐本书。书中穿插有perl语法形成的历史和原因,使你能充分感受到perl语言的文化,这也是perl流行的原动力。本书行文流畅,各知识点介绍到位,令人很容易明白,到达入门点睛的效果。但本书的作用也就是入门而已,目的很明确,它没有深入到perl脚本语言的高级部份。如果你想了解perl的高级功能或使用perl来更好地完成你的日常工作,还需进一步学习,?perl语言编程?应该是你最好的选择。第一章简介1第二章标量数据1第三章列表和数组3第四章子例程3第五章散列〔哈希hash〕3第六章I/O根底3第七章正则表达式的概念3第八章正则表达式提高3第九章使用正则表达式3第十章更多的控制构造3第十一章文件句柄和文件测试3第十二章目录操作3第十三章处理文件和目录3第十四章进程管理3第十五章字符串与排序3第十六章简单数据库3第十七章一些高级Perl技术3第一章简介第二章标量数据什么是村量数据.标量〔scalar〕是perl中最根本的元素。大多数标量要么是一个数字,要么是一个字符串。perl根本上把它们视为可相互替换的东西。数字所有数字的部格式都一样在部,perl一律把整数,浮点数按双精度浮点数进展计算。perl部没有整数值程序中的一个整数常量被当作等值的浮点数。直接量〔literal〕指的是在perl源代码中表示值的方式,浮点直接量1.33,233.5,-3.9整数据直接量0,89,-66,61_383_883_897_363〔一个大数,用下划线以示清晰〕非十进制整数直接量八进制直接量以0开头十六进制直接量以0*开头二进制以0b开头从5.6版本开场,perl允许在直接量中加下划线以示清晰。0*50_65_7c数值操作符加+2+3减-3-2乘*2*3除/2/3模%10%3指数**2**3字符串单引号字符串直接量在引号间除了单引号或反斜杠以外的任何字符〔包括换行符,如果该字符串连续占几行〕在字符串中表示该字符本身。要想得到一个斜杠,需要连续写两个斜杠,要得到一个单引号,需要加一个斜杠。双引号字符串直接量在双引号的反斜杠开场发挥它的作用,可以用来指定特定的控制字符。可以在双引号里面插变量。双引号的转义字符完整列表\n换行\r回车\t制表符\f换页\b退格\a响铃\eEsc(ascii的转义字符)\007任意ASCII码的八进制值〔这里007=响铃〕\*7f任意ASCII码的十六进制值〔这里07f=删除〕\cC任意Ctrl键组合字符〔这里是Ctrl-C〕\\反斜杠\"双引号\l下一个字母小写\L所有后面的字母小写,直到\E\u下一个字母大写\U所有后面的字母大写,直到\E\Q添加反斜杠引用后面的非单词字符,直到\E\E完毕\L,\U,\Q字符串操作符.连接两个字符串"hello"."world"="helloworld"*串重复操作符"yang"*3="yangyangyang"次数使用前截成一个整数。4.8=4,小于1的拷贝次数会得到一个空串。数字与字符串的自动转换依赖于作用在标量值上的操作符。如果是+则是数据,如果是.则是字符串。"z".6*7="z42","12"*"3"=36perl的置警告可以要求perl在发现你程序有异常时给你一个警告。使用-w选项。*!/usr/bin/perl-w标量变量变量〔variable〕是一个容器的名字,用以存放一个或多个值,变量的名字在程序中保护不变,但它所包含的值在执行过程中一般要不停地改变。在perl中用美元符号标识。$a,$test。选择好的变量名适当加一些下划线可让变量更易读,更易理解。标量赋值〔assignment〕操作符用等号,它的左边是变量名,右边是值。二元赋值操作符+=-=*=.=**=andsoon用print输出print"helloworld\n";print"theanswer",6*6,".\n";在字符串中替换标量变量$meal="brontosaurussteak";$barney="fredatea$meal";另一种写法$barney='fredatea'.$meal;如果标量变量从未被赋过值,就用一个空串替换。操作符优先级和结合性善用小括号perlk中的操作符优先级和结合性与C一样比较操作符相等==eq不相等!=ne小于<lt大于>gt小于等于<=le大于等于>=geif控制构造if(){...;}else{...;}布尔值perl中没有单独的的布尔数据类型,不过,它使用几条简单的规则。1、特殊值undef是假。2、0是假,所有其它的数字是真。3、空串''是假,所有其它的字符串一般是真。4、一个例外,因为数字和字符是等价的,所以0的字符形式'0',和它的数值形式有同样的值:假。!是取反的意思,可以在真值前加,结果就变成了假。取得用户输入<STDIN>从键盘得到一个值。一般以\n字符完毕。所以可利用该字符做条件控制。chomp操作符它作用于一个变量,此变量必须存放一个字符串,如果这个字符串以换行符结尾,chomp就把它去掉。$te*t="alineofte*t\n";chomp($te*t);去掉换行符chomp($te*t=<STDIN>);最常用的方法,读文本,不带换行符chomp是一个函数,所有它有返回值,即去掉的字符个数。使用chomp时可以带或不带小括号,这是perl的另一个根本规则,除非去掉括号会改变意思,否则括号总是可有可无的。while控制构造重复执行一个代码块,只要条件为真。$count=0;while($count<10){$count+=1;print"countisnow$count\n";得到从1到10的值。}undef值变量在第一次赋值之前有特别的undef值,代表什么也没有。当把它作为字符串时,其功能相当于一个空串。当把它作为数字时,其功能相当于0。perl程序员经常这样使用。很多操作符在操作数超出围或没有意义时会返回undef值,这样一般不是什么问题,但如果翻开perl的警告,则会导至一个警告。defined函数测试一个值是undef还是非空字符串,可以使用这个函数。它对undef返回假,其它所有情况则返回真:$madon=<STDIN>;if(defined($madon){print"theinputwas$madon";}else{print"noinputavailable!\n";}如果你想生成自已的undef值,可以用古怪的undef操作符$madon=undef;好似它从来没有被动过第三章列表和数组在perl中,如果“单数〞是标量,则“复数〞则由列表和数组来表示。列表(list)是一个有序的标量集合,数组(array)是一个包含列表的变量。准确地说,列表是数据,而数组是变量,可以有一个不在数组的列表,但每个数组变量都包含一个列表。数组和列表可以放任意多的元素,最小的是没有元素,而最大的可以把所有存耗尽。这符合perl的“没有不必要的限制〞哲学。访问数组的元素数组元素用连续的整数编号,从0开场,然后按1递增。$fred[0]="a";$fred[1]="b";$fred[2]="c";如果下标所指的元素超出了数组的区间,则相应的值就是undef。特殊的数组索引如果你试图存储一个超出数组区间的数组元素,这个数组就会自动按需扩展,对它的长度没有限制,只要有足够的存供perl使用。$rocks[0]="a";$rocks[1]="b";$rocks[2]="c";$rocks[10]="end";现在就有6个undef元素。访问最后一个元素的索引是$*rocks。负的数组索引从数组尾部算起,-1代表最后个元素。列表直接量列表直接量(listliteral)是小括号中的一列由逗号分隔的值。例如:〔1,2,3,4〕〔“fred〞,43.4〕〔〕〔1..100〕〔0..$*rocks〕“..〞是区间操作符,能生成一个顺序列表。如上例中的从1到100。列表可包含表达式或变量。qw快捷方式qw表示“被括引的单词〞〔quotedwords〕或“用空白括住〞〔quotedbywhitespace〕,perl按单引号字符串处理它们,所以你不能像在双引号字符串中那样在qw列表中用\n或$fred〕。qw/abcd/等同于("a","b","c","d")qw!abcd!等同于("a","b","c","d")qw{abcd}等同于("a","b","c","d")定界符可以选择任意的标点。列表赋值($fred,$barney,$dino)=("a","b","c")($fred,$barney)=($barney,$fred)交换它们的值,比c等语言方便很多。如果变量的个数小于值的个数,则多余的值会被无声地忽略。如果变量的个数多于值的个数,则多的变量会得到undef值。at符号可以一次指定整个数组。这样rocks代表“所有的rocks〞。rocks=qw/abc/;copy=quarry从一个数组拷贝一个列表到另一个数组popandpush操作符正真的perl程序员不使用索引访问数组,这样发挥不了perl的强项。我们经常把数组当信息栈用。总是从列表的右侧参加新值或删除。pop操作取出一个数组的最后一个元素array=5..9;$fred=pop(array);$fred得到9,array现在有(5,6,7,8)$barney=pop(array);$barney得到8,array现在有(5,6,7)如果数组是空的,pop就不管它,因为没有元素可删除,只返回undef。push操作与pop对应,它顺数组的最后添加一个元素或一个元素列表。push(array,0);array现在有(5,6,7,0)others=qw/123/;pusharray,othersarray现在有(5,6,7,0,1,2,3)注意:push的第一个参数或pop的唯一参数必须是一个数组变量,进栈和出栈对直接量列表来说是没有意义的。shiftandunshift操作类似于pushandpop,shiftandunshift对数组的头部进展相应的操作。在字符串中替换数组与标量一样,数组的值也可以被替换到双引号字符串中。print"quartzrockslimestone\n";打印所有岩石,用空格分开。注意:不要把电子地址放到双引号字符串中。foreach控制构造foreach循环遍历列表中的所有值,对每个值执行一个迭代〔执行一次循环体〕foreach$rocks(qw/abc/){print"onerockis$rocks.\n";打印abc。}Perl最喜欢的缺省变量:$_如果你在foreach循环的开场忽略了控制变量,perl就会使用$_。foreach(1..10){缺省使用$_print"Icancountto$_!\n";}$_="a";print;缺省打印$_reverse操作符reverse取一个列表的值,然后返回相反顺序的列表。记住它只返回反序列表,并不影响它的参数,如果返回值不被赋给别的变量,它是不保存。sort操作符sort取一个列表的值,然后按照部字符序进展排序。标量和列表上下文一个给定的表达式在不同的地方,可能会有不同的含义。5+somethingsomething必须是个标量sortsomethingsomething必须是个列表在标量上下文中使用列表生成表达式提供标量上下文的表达式:$fred=something;$fred[3]=something;123+somethingsomething+654;if(something){...}while(something){...}$fred[something]=something;提供列表上下文的表达式:fred=something;($fred,$barney)=something;($fred)=something;pushfred,something;foreach$fred(something){...}sortsomething;reversesomething;printsomething;在列表上下文中使用标量生成表达式如果一个表达式在正常情况下不生成一个列表值,则自然它就会生成标量值,即一个元素列表:fred=6*7得到一个单元素列表(42)注意,因为undef是个村标量值,所以给一个数组赋undef并不能清空数组,清空的更好方法是赋一个空列表〔〕。强制使用标量上下文可以使用scalar假函数,它告诉perl提供一个标量上下文。rocks=qw/abcd/;print"ihave",rocks,"rocks!\n";错,打印了石头的名字print"ihave",scalarrocks,"rocks!\n";正确,打印石头的数量列表上下文中的<STDIN>chomp(lines=<STDIN>);读入那些行,不带换行符第四章子例程系统与用户函数perl的子例程可以让我们在一个程序中重复利用一块代码,子例程名字是在前面加一个可有可无的&符号,有一条规则规定什么时候可以省略。定义一个子例程使用关键字sub和子例程名定义。可以放在程序的任何位置。submarine{$n+=1;print"hello,sailornumber$n!\n";}注意:n为全局变量调用子例程$marine;输出hello,sailornumber1!$marine;输出hello,sailornumber2!返回值每个子例程在运行过程中,计算值是它一系列动作的一部份。在子例程中得到的最后一个计算值自动成为返回值。因此注意在向子例程增加代码时要确保最后一个表达式的结果是你希望的返回值。“最后一个表达式〞是指真正的、被最后计算的表达式,而不是正文的最后一行。参数参数列表在子例程运行期间被自动地赋给一个特别的数组变量_。子例程可以访问这个变量以确定参数个数和参数的值。也就是说,第一个参数被存在_[0],第二个被存在_[1]中,其它依次类推。_变量是子例程的局部变量,如果_中有一个全局变量,它就会在子例程调用前被保存起来,而在子例程返回时恢复原值。子例程中的私有变量my操作符生成被称为词法变量〔le*icalvariable〕的私有变量。local操作符local的真正功能是把给定的变量的一个拷贝保存在一个秘密的地方〔栈〕。这个值在保存后不能被访问、修改、删除,读出、检查、打印等。在perl中没有方法以接近被保存的值。接着local把该变量设为空值〔对标量是undef,对数组是空表〕,或设为任何赋给它的值。当perl从子例程中返回时,会自动将变量恢复为原先的值。从效果上来看,这个变量被暂时借用了片刻。local和my的区别local是全局变量,可以想成“save〞〔在子例中调用时〕,在所有新代码中只用my,my比local快。可变长参数列表在perl中,经常传递给子例程任意长度的参数列表。子例程可以查看_数组,从而轻松地判断参数的个数。但在实际的perl编程中,这类检查几乎没有用过,最好是让子例程适应参数。一个允许任意参数的例程$ma*imum=&ma*(3,5,10,4,6);subma*{my($ma*_so_far)=shift_;foreach(_){if($_>$ma*_so_far){$ma*_so_far=$_;}}$ma*_so_far;}这段代码使用了被称作“高水位线〔high-watermark〕的算法。在一次洪水之后,当水最后一次涨潮和退潮时,高水位线显示了曾经到达的最高水位。空的参数列表返回一个undef。词法(my)变量的说明my可以在任何块中使用,而不仅仅在子例程中。例如可以在if,whileorforeach中。usestrictpragmaperl是一种特别宽松的语言,但也许你想让perl把规则加强一些,这可以用userstrictpragma〔编译指示〕来安排。pragma中给编译器的提示,告诉它关代码的一些信息,这里,usestrictpragma是告诉perl编译器,它应该在本块或源文件的其余部份强制使用一些好的程序设计规则。return操作符该操作符立即从子例程中返回一个值。省略与字符(&)原则在除与置函数名一致,其它子例程都可以省略与字符。第五章散列〔哈希hash〕什么是散列.散列〔hash〕是一个数据构造,与数组一样的是它可以含有任意数目的值并随意读取它们。但与数组中由数字对值进展索引不同,散列用名字〔name〕查找值。也就是说,索引不再是数字,而是任意的惟一字符串,称之为键〔key〕。它是一桶数据,不存在第一项,它是一团糟的,随意的,没有固定的顺序。键总是被转成字符串,如用数值50/20做键,它就会被变成“2.5〞。散列可以任意大小,从空散列直以填满存。在perl中巨大的散列并不可怕,从三个和三百万个键值对中取出一个数的速度差不了多少。为什么要用散列你有一组数据与另外一组数据相关。如名姓主机名ip地址ip地址主机名单词单词出现的次数用户名用户使用的硬盘块数驾照名字如果你的任务描述中包含“找到重复项〞,“唯一的〞,“穿插引用〞,或“查表〞之类的词语,则散列就会在实现中很有用处。散列元素访问使用如下语法:$hash{$some_key}$a{"home"}="first";$a("hotel"}="second";当你在一个已存在的散列中存入东西时,会覆盖以前的值。访问散列之外的元素会得到undef:$a=$b{"test"};这里没有test,得到undef。作为一个整体的散列要访问整个散列,就使用%号做前缀。为方便起见,可以将散列转换为一个列表,并转换回来,给散列赋值是一个列表上下文,这个表由键-值对组成%hash=("aa",33,"bay",11,2.5,"hello","cc","bb\n");展开散列〔unwind〕,把散列转换回键-值对应列表。次序乱了,但键-值还是成对出现的。array=%hashprint"array";bay,11,2.5,hello,cc,bb(一个换行符),aa,33散列赋值%new_hash=%old_hashperl将%old_hash展开成一个键-值对列表,并赋值给%new_hash。%inverse_hash=reverse%any_hash生成逆散列,键变值,值变键。前提是原散列值要唯一。大箭头用大箭头把散列中的键-值对组织起来。my%hash=("aa"=>"test1","bb"=>"test2","cc"=>"test3",最后额外的逗号是无害的);散列函数keys函数得到一个散列中所有当前键构成的一个列表,values函数得到一个相应的值。my%hash=("a"=>"test1,"b"=>"test2","c"=>"test3");myk=keys%hash得到"a","b","c"。myv=values%hash得到"test1","test2","test3"。在一人标量上下文中,这些函数给出散列的元素个数。my$count=keys%hash得到3,即有三个键-值对。each函数该函数可以遍历一个完整的散列。每次返回一个键-值对作为一个二元元素列表。最后返回一个空列表。while(($key,$value)=each%hash){print"$key=>$value\n";}e*ists函数查看*键是否在散列中。存在就返回真,不存在就返回假。delete函数从散列中删除指定的键〔和相应的值〕。如无此键,它的任务就完毕。此时没有警告或出错信息给出来。第六章I/O根底从标准输入进展输入while(defined($line=<STDIN>)){print"Isaw$line";};因为行输入操作符在你到达文件末尾时会返回undef,所以可以用它方便地跳出循环。从钻石操作符进展输入“<>〞是一种特殊的行输入操作符,它可以是也可以不是来自键盘的输入。while(defined($line=<>)){chomp($line);print"Itwas$linethatIsaw!\n";};如果用a,b,c三个参数调用该程序,将打印三个文件的容。使用钻石操作符,就好似输入文件被合并到一个大文件中。上面程序可用快捷方式写成:while(<>){chomp;print"Itwas$_thatIsaw!\n";};大多数linu*标准工具中,短横-代表标准输入流。通常在一个程序中只用一个钻石操作符,当初学者在程序中放第二个钻石时,其实他们一般是想用$_。记住,钻石操作符读取输入,但输入本身是在$_中。调用参数钻石操作符并不是直接从字面上读取调用参数,它实际上读取ARGV数组。它被perl解释器预设为调用参数的列表。在程序中可以对该数组进展赋值等操作。ARGV=qw*abc*;强制读取这三个文件while(<>){chomp;print"Itwas$_thatIsaw!\n";};向标准输出进展输出printarray;aabbccprint"array";aabbccprint<>;cat的源代码printsort<>;sort的源代码用printf进展格式化输出,和c类似。数组与printf可动态形成格式字符串。myitems=qw(abc);my$format="theitemsare:\n".("%10s\n"*items);在标量上下文中使用items得到它的长度printf$format,items在列表上下文中使用items得到它的容上下文太重要了。要好好感受。第七章正则表达式的概念正则表达式〔regulare*pression〕,在perl中经常被称为模式〔pattern〕,是与一个给定字符串匹配或不匹配的模版。不要把正则表达式和被称为glod的shell的文件名匹配模式混淆。比方*.pm匹配以.pm结尾的文件名。使用简单的模式要比较一个模式和$_的容,只需把模式放在一对斜杠之间,如下:$_="aabbkdkdk";if(/aabb/){print"itmatched!\n";};关于元字符在正则表达式中有一组具有特殊意义的字符,叫元字符,如:.号匹配任意单个字符〔但不匹配换行符〕,加反斜杠会使它不再特殊。一对反斜杠配置一个真正的反斜杠。简单的数量符在模式中重复一些东西。*号匹配前面的条目0次或屡次。如:/foo\t*test/匹配在foo和test间任意数目的制表符。.*匹配任意字符、任意次数。+匹配前面的条目一次或屡次。.匹配前面的条目是可选的,只能发生一次或0次(即没有)。模式中的分组可以用〔〕括号分组,所以小括号也是元字符。如:/abc+/匹配abccccccccccccccccc/(abc)+/匹配abcabcabcabcabc/(abc)*/匹配任意字符串,甚至是空串。选择竖线|表示要么是左侧匹配,要么是右侧匹配。此时读做“或〞。/aa|bb|cc|/匹配一个含有aa或bb或cc的字符串。/aa(|\t)+bb/匹配aa和bb中间被空格、制表符或两者的混合串分隔/aa(+|\t+)bb/匹配aa和bb中间必须全是空格,或全是制表符/aa(and|or)bb/匹配aaandbb和aaorbb一个模式测试程序下面这个程序有助于在一些字符串上测试一个模式,看看它匹配了什么,在哪里匹配的。*!/usr/bin/perlwhile(<>){chomp;if(/your_pattern_goes_here/){print"Matched:|$`<$&>$'|\n";}else{print"Nomatch.\n";}};第八章正则表达式提高字符类字符类〔characterclass〕即在一对中括号中列出的所有字符,可以匹配类中的任何单个字符。例如:[abcdefg]可以匹配这七个字符中的任何一个。可用“-〞指定一个围。如[a-h],[1-9]等。[\001-\177]匹配任何7比特ASCII码。中括号中的“^〞号是取反的意思,如[^abc]匹配除abc外的任何单个字符。字符类快捷方式有些字符类的使用特别频繁,所以就有了快捷方式。如:所有数字的字符类[0-9]可以缩写成\d,[A-Za-z0-9_]缩写成\w。\s匹配空白,它和[\f\t\n\r]等同,即等同一个含五种空白字符的字符类,它们是换页符,制表符,换行符,回车符和空格字符自已。\s只匹配类中的一个字符,所以一般用\s*匹配任意数量的空白〔包括没有空白〕,或用\s+匹配一个或多个空白字符。以上快捷方式的反置写法是用大写形式表示,\D,\W,\S。/[\dA-Fa-f]/匹配十六进制数字。/[\d\D]/匹配任何数字或任何非数字,也就是任何字符,包括换行符。“.〞匹配除换行符外的所有字符。/[^\d\D]/表示什么都不匹配。通用数量符前面我们见过三个数量符*,+,?。但如果这三个不能满足你的需要,也可以用大括号{}中的一对由逗号隔开的数字来指定重复的最少和最屡次数。如/a{5,15}/匹配重复5次到15次的字母a。如果省略第二个数〔但包含逗号〕,则匹配的次数就没有上限。如/a{3,}/就匹配一行中连续出现的3个或多个a,它没有上限。如果连逗号也没有了,则给出的数字就是一个准确的数字。如/a{3}/匹配3个a。*等价{0,}+等价{1,}?等价{0,1}锚位符锚位符〔anchor〕可以用来为模式指定字符串的特定位置。“^〞标志字符串的开头,“$〞标志字符串的结尾。如/^a/匹配处于字符头的abc,不能匹配dda,/b$/匹配处于字符尾的aab,不能匹配abc。/^s*$/匹配一个空行/^abc$/匹配abc,又匹配abc\n单词锚位符\b可以匹配一个单词的两端,可以用/\babc\b/来匹配单词abc。可以用一个单词锚位符,如,/\bth/可以匹配this,these,但不匹配method。/er\b/匹配hander,woner,但不匹配gerenic,lery.非单词边界锚位符是\B,它匹配任何\b不匹配的地方。如/\bsearch\B/会匹配searches,searchingandsearched.但不能匹配searchorresearching。记忆的小括号()可以用来把模式的一些部份组合起来,它还有第二个功能,它们要求正则表达式引擎记住与小括号中的模式匹配的那部份子串。反向引用反向引用〔backreference〕就是回头引用在当前模式处理过程中保存的记忆。用一个么斜杠来构成,如\1包含第一个正则表达式记忆。即被第一对小括号匹配的字符串部份。反向引用被用来匹配与模式在前面匹配的字符串完全一样的字符串。所以/(.)\1/匹配任意单个字符,在记忆1中记住它,然后再与记忆1匹配。换句话说,它匹配任意字符,后跟同一个字符。这样,这个模式会匹配双字母式的字符串。如bamm-bamm和betty。它和/../不一样,/../匹配任意字符,后跟任意字符,它们两个可以一样,也可以不一样。记忆变量正则表达式记忆的容在模式匹配完毕后仍可通过特殊变量$1得到。优先级分四个级别1、最上面的是小括号。2、是数量符,*,+,.,{1,2},{1,},{1}3、是锚位符和序列,^,$,\b,\B。4、是坚线|。优先级例子/^aaa|bbb$/可能不程序员的意思,它只匹配字符串aaa的开头或字符串bbb的未尾。程序员更可能想要的是/^(aaa|bbb)$/,它匹配一行中没有其它东西,除了aaa或bbb以外。第九章使用正则表达式使用m//进展匹配一对斜杠实际上是m//(模式匹配)操作符的一个快捷方式。如我们在qw//中所中,你可以选择任何定界符对把容括住。如m<aaa>,m(aaa),m{aaa},m[aaa],m!aaa!等。如果选择了反斜杠,就可以省略m。选项修饰符用/i进展不区分大小写的匹配。用/s进展任何字符的匹配,包括换行符。它把模式中的每个点变成和字符类[\d\D]一样,匹配任何字符,包括换行符。可组合使用修饰符/is,顺序并不重要。绑定操作符=~my$some_other="Idreamofbettyrubble";if($some_other=~/\brub/){print"Aye,there'stherub.\n";}看起来像个赋值语句,但它不是的。它是说“这个模式缺省时匹配$_中的东西但现在让它匹配左侧的字符串〞。如果没有绑定操作符,表达式就缺省使用$_。匹配变量可以用$1,$2,$3,$4引用正则表达式记忆的第一到第四个记忆。匹配变量是正则表达式强大功能的一个重要部份,它能让我们取出一个字符串的一部份。$_="hellothere,neighbor";if(/\s(w+),/){记住空格和逗号之间的单词print"thewordwas$1\n.";$1就是there}匹配变量可以是空串。记忆的持久性匹配变量一般保存到下一次模式匹配成功。也就是除非匹配成功,否则你不应该使用这些匹配变量。自动匹配变量$&实际与模式匹配的那部份字符串就保存在这里。if("hellothere,neighbor"=~/\s(w+),/){print"thatactuallymatched'$&'.\n";}整个匹配部份是"there,"〔一个空格,there,一个逗号〕,$1中是there,而$&中是整个匹配部份。匹配部份之前的东西被存在$`,之后的东西被存在$'。也就是说,$`含有正则表达式引擎在找到匹配之前需跳过的部份,而$'则含有模式没有到达的字符串的剩余部份。如果把这三个字符串按顺序连在一起,则你总会得到原字符串。第七章的模式测试程序就是使用了这三个神秘代码。print"match:|$`<$&>$'|\n"使用自动匹配变量的代价是,会使用其它正则表达式的运行会变得慢一些。所以很多perl程序员都尽量防止使用这些自动匹配变量。相反,他们会采用一些方法,例如,如果你只需要$&,那就在整个模式的周围加一对括号,然后使用$1。用s///进展查换并替换$_="he'soutbowlingwithbarneytonight.";s/barney/killer;用killer替换barney,如果匹配失败,什么也不会发生。print"$_\n";s///有一个返回值,替换成功,则为真,否则为假。用/g进展全局替换s///只替换一处,/g修饰符告诉s///进展所有可能的无交迭替换。全局替换的一个相当常见的使用是压缩空白,把任意数量的空白变成一个空格。s/\s+//g;压缩空白s/^\s+//;把前面的空白删除s/\s+$//;把结尾的空白删除s///也可用不同的定界符,如*,!号等,但如果使用成对的字符,因为它有左右之分,所以必须用两对,一结放模式,一对放替换串,如s[aaa][bbb],s(aaa)(bbb),甚至也可以用s<aaa>(bbb)这样不成对的定界符。s///也和m//一样,有/i,/s修饰符和=~绑定操作符。$file_name=~s/^.*///s;在$file_name中,去掉所有uni*风格的路径。大小写转换\U强制后面的字符都用大写s/(aaa|bbb)/\U$1/giAAABBB\L强制后面的字符都用小写s/(aaa|BBB)/\L$1/giaaabbb用\E关闭,当写成小写形式时,\u,\l就只影响下一个字符。\u\L或\L\u代表首字符大写,与顺序无关。split操作符它把一个字符串按照分割子〔separator〕分开。fields=split/:/,"abc:def::a:b";得到〔"abc","def",","a","b"〕。fields=split/:/,":::a:b:c:::";得到〔",",","a","b","c"〕,结尾空字段被丢弃。在空白处分割也是常见的,使用/\s+/模式。split的缺省行为是在空白处分割$_。如myfields=split;等同于split/\s+/,$_;join函数在*种意义上,join完成split的相反过程。它把一组片断粘合起来形成一个字符串。my$a=join":",1,2,3,4,5;则$a是"1:2:3:4:5"join可以和split配合使用,把一个字符串分割后用不同的定界符恢复它。如可以把1,2,3变成1-2-3.第十章更多的控制构造unless控制构造if是表达式为真时执行,如果希望表达式为假时执行可用unless〔除非〕。表示除非表达式为真,否则运行这个代码。它就像一个具有相反条件的if语句,也可以理解成一个独立的else子句。unless($aa=~/^[A-Z_]\w*$/i){print"thevalueof\$aadoesn'tlooklikeaperlidentifiername.\n";}等同于if($aa=~/^[A-Z_]\w*$/i){}else{print"thevalueof\$aadoesn'tlooklikeaperlidentifiername.\n";}等同于if(!$aa=~/^[A-Z_]\w*$/i){print"thevalueof\$aadoesn'tlooklikeaperlidentifiername.\n";}以上语句都被编译成一样的部字节码,但unless最自然。unless的else子句unless($aa=~/^(bb)/){print"thisvaluelikebb.\n";}else{print"doyouseewhat'sgoingonhere?\n";}等同于if($aa=~/^(bb)/){print"doyouseewhat'sgoingonhere?\n";}else{print"thisvaluelikebb.\n";}until控制构造while的反置构造。until($a>$b){$a*=2;}这个循环一直执行,直到条件表达式返回真为止。表达式修饰符print"$nisanegativenumber.\n"if$n<0;等同于if($n<0){print"$nisanegativenumber.\n";}前一种写法更紧凑。读起来很像自然英语。还有:print"",($n+=2)while$n<10;$i*=2until$i>$j;&greet($_)foreachperson;裸块控制块所谓的“裸〔naked〕块〞,指的是没有关键字或条件的块。如:while(condition){body;body;body;}现在把while关键字和条件去掉,就得到一个裸块。{body;body;body;}它只执行一次,然后就完毕,其中一个作用是提供一个临时词法变量的作用域。一条通用的原则,所有变量就应该在最小的作用域中声明。如果你需要一个只用在几行代码中的变量,则你可以把这些行放在裸块中,并在该块中声明这个变量。elsif子句如果你需要检查一组条件,一个接一个,看看哪个条件为真,就可以用elsif子句〔注意不是elseif〕。perl会逐个测试条件表达式,当一个条件成功就执行相应的代码。但如果测试项太多,就不要使用这种方式,应该用类“caseorswitch〞的语句。自递增和自递减++$a++;$a值不变。++$a;把$a增1,存到$a里。--$a--;$a值不变。--$a;把$a减1,存在$a里。for控制构造for($i=1;$i<=10;$i++){print"Icancountto$i!.\n";}for($_="aaabbbccc";s/(.)//;){当s///成功时执行循环。print"onecharacteris:$1\n."}每次迭代时都会去掉一个字母。当字符串为空时,替换失败,循环完毕。以下用for实现的无限循环for(;;){print"thisisaninfiniteloop.\n";}以下为用while实现的无限循环,一种更具perl特色的写法。while(1){print"thisisaninfiniteloop.\n";}foreach和for之间的秘密联系在perl部,foreach和for完全等价。for(1..100){实现是一个从1到100的foreach循环print"Icancountto$_.\n";}在perl中,foreach总是被写成for,因为可节省4个字符的输入,因为懒惰是perl程序中的经典品质。循环控制last操作符立即终止一个循环的执行〔与c中的break相似〕。作用于当前运行的最层循环块。ne*t操作符控制从循环的下一个迭代继续〔与c中的continue相似〕redo操作符回到当前循环的开头,但不测试条件表达式,进入下一次迭代。ne*t和redo最大的区别在于ne*t会进入到下一次迭代,而redo则重新执行当前的迭代。带标签的块很少使用,也就是命令一个循环,以便从层循环中直接跳出。LINK:while(<>){foreach(split){lastLINKif/__END__/;跳出LINE循环。...;}}逻辑操作符&&相当于and||相当于or它们被称为短路操作符。三元操作符?和c的一样,它就像一个if-then-else测试。e*pression?if_true_e*pr:if_false_e*pr一个利用三元操作符写的多路分支程序my$size=($width<10)?"small":($width<20)?"medium":($width<50)?"large":"e*tra-large";缺省值。使用部份计算操作符的控制构造&&,||,?:都有一个共有的属性,依赖于左侧值的真假,它们可能计算可不计算一个表达式,因此叫部份计算〔partial-evaluation〕操作符。因此它天生就是一种控制构造。第十一章文件句柄和文件测试什么是文件句柄.文件句柄〔filehandle〕是Perl程序中的一个名字,表示你的Perl进程与外面世界的i/o连接。它是一个连接的名字,并不是一个文件的名字。文件句柄的命名方式与其它perl标识符一样,建议用大写字母。Perl为了自已使用,已经有六个特殊的文件句柄名:STDIN,STDOUT,STDERR,DATA,ARGVANDARGVOUT。翻开一个文件句柄openCONFIG,"test";翻开test文件,它所包括的东西通过名为CONFIG的文件句柄为我们的程序所使用。openCONFIG,"<test";翻开test文件,显式说明这个文件名用于输入。openCONFIG,">test";翻开test文件,显式说明这个文件名用于输出。为了输出翻开文件句柄CONFIG到新文件test。openCONFIG,">>logtest";翻开logtest文件,用于附加。如果文件不存在则生成它。关闭一个文件句柄closeCONFIG;退出程序时文件句柄会自动关闭,但建议最好在完成一个文件句柄的使用后不久就关闭它。坏文件句柄系统中会存在坏文件句柄,如果你试图向一个坏文件句柄写入,则数据会被无声地丢弃。在编写脚本时用perl-w会翻开警告显示。用die说明致命错误unless(openLOG,">>logtest"){die"Cannotcreatelogtest:$!";}或者用另外一种更好的写法openLOG,">>logtest"ordie"Cannotcreatelogtest:$!";使用or操作符。如果open成功,返回真,or完毕,如果open失败,返回假,or会继进展到右侧代码。伴随一条消息死去。你可以用语言去读它,“翻开这个文件,或死去〞。$!是系统给出的出错提示信息,如果die说明的错误并非来自一个系统请示失败,请不要包含$!。die"Notenouhtarguments.\n"ifARGV<2;命令参数不够两个时,程序退出。使用warn发出警告信息与die类似,但它不退出程序。使用文件句柄一旦翻开一个文件句柄,你就可以读入行。像使用STDIN从标准输入读取一样。例如从uni*的passwd文件中读取行:openPASSWD,"/etc/passwd"ordie〞Howdidyogetlogedin?($!)";一个为写入或附加翻开的文件句柄可以和printorprintf一起使用,紧跟在其后但在参数列表之前:printLOG"filehandletest.\n"输出到LOG改变缺省的输出文件句柄缺省情况下,如果没有给print指定一个文件句柄,输出就会发送到STDOUT,但这个行为可以用select操作符改变。selectLOG;print"thismessagesendtoLOG.\n";一旦选择一个文件句柄作为缺省的输出,它会一直保存,这样会把后面的程序搞糊涂,所以要在完成后及时设回STDOUT。selectSTDOUT;重新翻开一个标准文件句柄如果三个系统句柄(STDIN,STDOUT,STDERR)的任何一个不能翻开,Perl会友好地恢复原来的那个,也就是说perl只有在看到新的连接翻开成功时帮把原来的关掉。文件测试在perl中有一组完整的测试,你可以用来了解文件的信息。-e测试文件是否存在die"ooo!mygods,afilecalled"$file"alreadye*ists.\n"if-e$file;-M检查一个文件是否最新warn"configfileislookingprettyold!\n"if-MCONFIG>28;文件测试和它们的含义-r文件或目录对该〔有效〕用户或组可读-w文件或目录对该〔有效〕用户或组可写-*文件或目录对该〔有效〕用户或组可执行-o文件或目录被该〔有效〕用户或组所有-R文件或目录对该实际用户或组可读-W文件或目录对该实际用户或组可写-*文件或目录对该实际用户或组可执行-O文件或目录被该实际用户或组所有-e文件或目录名存在-z文件存在,大小为零,对目录总为假-s文件或目录存在,大小非零,单位为字节-f条目是个普通文件-d条目的个目录-l条目是个符号-S条目是个套接字-p条目是个命名管道〔一个fifo〕-b条目是个块特殊〔block-special〕文件〔如一个可装载磁盘〕-c条目是个字符特殊〔character-special〕文件〔如一个i/o设备〕-u文件或目录是setuid-g文件或目录是setgid-k文件或目录的粘着位stickybit被设置-t文件句柄是个TTY〔可以由isatty()函数返回,文件名不能由本测试来测试〕-T文件像个“文本〞文件-B文件像个“二进制〞文件-M更改年龄〔单位为天〕-A访问年龄〔单位为天〕-CInode更改年龄〔单位为天〕stat和lstat函数stat返回uni*的stat系统调用返回的所有信息。它的操作数是一个文件句柄或是一个文件名。返回值可能是一个空列表,表示stat失败〔通常是文件不存在〕,或者是一个13个元素的数字列表。可用以下标量变量列表描述出来。my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)=stat($filename);$dev文件设置号$ino文件inode号$mode文件权限位和一些特别位$nlink指向文件或目录的数$uid文件的用户id$gid文件的组id$size文件大小〔以字节为单位〕$atime$mtime$ctime访问,修改,改变时间$blksize块大小$blocks块数对符号使用stat将返回该所指的东西的信息,而不是符号本身,除非这个碰巧没有指向任何目前可以访问的东西。如果你需要〔根本上没用〕符号本身的信息,就使用lstat。如果操作数不是一个符号,lstat则返回与stat一样的东西。localtime函数把电脑时间转换成人可以看得明白的日期时间。my$timestamp=my$date=localtime$timestamp在列表上下文中,localtime返回一个数字列表。my($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst)=localtime$timestamp$mon表示月份,从0-11。$year表示自1900年起的年数,要加上1900才是真正的年数。按位操作符&按位与得到哪些位在两个操作数中同时为真|按位或得到哪些位在两个操作数中至少有一个为真^按位异或得到哪些位在两个操作数中只有一上为真<<按位左移把左操作数的位移动由右操作数给定的次数,在低位补上0>>按位右移把左操作数的位移动由右操作数给定的次数,低位会被丢弃~按位取反,也被称为一元位补返回与操作数的每位相反的数使用位串如果一个按位操作符的任何操作数是一个字符串,perl就会进展位串操作。也就是说"\*AA"|"\*55"会得到字符串"\*FF"。使用特殊的下划线文件句柄_特殊的文件句柄,使perl用上次文件测试、stat,lstat函数操作后留在存中的信息。第十二章目录操作改变目录树chdir操作符可以改变工作目录,就像cd命令一样。chdir"/etc"ordir"cannotcddirto/etc:$!";globshell通常会把每个命令中的文件名模式扩展为匹配的文件名,这就称为glod。如ls*.t*tperl中的类似的glob操作符。myall_files=glob"*";得到当前目录中的所有文件,不包含以句点开头的文件。mypm_files=glob".pm";得到以.pm结尾的文件。glob的另一种作法在一些老程序中用<>代替glob操作符myall_files=<*>;目录句柄目录句柄〔directoryhandle〕和文件句柄在外表和操作上都很像,可以翻开它〔用opendir〕,读取它〔用readdir〕,关闭它〔用closedir〕。它读出的是目录的容。my$dir_to_process="/etc";opendirDH,$dir_to_processordie"cannotopen$dir:$!";foreach$file(readdirDH){print"onefilein$diris$file\n";}closedirDH;与文件句柄类似,目录句柄会在程序完毕时或该目录句柄在其它目录上重新翻开时被自动关闭。如果我们只想要那些以pm结尾的文件,可以在循环中使用一个跳过函数while($name=readdirDIR){ne*tunless$name=~/\.pm$/;}如果要非点文件可以用:ne*tif$name=~/^\./;如果想要除.和..之外的文件可用:ne*tif$nameeq"."or$nameeq"..";readdir操作符返回的文件没有路径名部份,仅仅是目录的文件名。如passwd,而不是/etc/passwd名字补丁,加上路径名。opendirSOMEDIR,$dirnameordie"cannotopen$dirname:$!";while(my$name=readdirSOMEDIR){ne*tif$name=~/^\./;跳过点文件$name="$dirname/$name";补上路径名ne*tunless-f$nameand-r$name只要可读文件}递归的目录列表递归地访问目录可用File::Find库。以进展简洁的递归目录处理。不用自已写代码。第十三章处理文件和目录删除文件在perl中用unlink操作符删除文件,同shell的rm命令一样。unlink"aa","bb","cc";把这三个文件删除。与glob函数结合起来可以一次删除多个文件unlinkglob"*.o";删除当前目录下以.o结尾的文件,与rm*.o相似。unlink的返回值告诉我们有多少文件被成功删除。my$successful=unlink"aa","bb","cc";print"Idelete$successfulfile(s)justnow.\n";如果想知道那个文件被删除,可用循环,一次删除一个文件。foreachmy$file(qw/aa,bb,cc/){unlink$fileorwarn"failedon$file:$!";}一个很少人知道的有关uni*的事实。如果你有一个文件,你对它不能读,不能写,不能执行,甚至文件可能并不属于你,但你仍然可以删除它。这是因为unlink一个文件的权限不依赖于文件本身的权限位,起作用的其实是包含这个文件的目录的权限位。只要目录是可写的,就可以删除该目录中不属于自已的文件。在uni*中可以通过设置stickybit解这个问题,以保护可写目录。重命名文件rename"old","new";类似于mv命令。rename失败时返回假,并在$!中设置操作系统的错误信息。因此可用ordie或orwarn显示给用户。一个把所有以.old结尾的东西rename为以.new结尾的perl程序。foreachmy$file(glob"*.old"){my$newfile=$file;$newfile=~s/\.old$/.new/;由于.new不是模式,所以点号不用加反斜杠。if(-e$newfile){warn"can'trename$fileto$newfile:$newfilee*ists.\n";}elsif(rename$file,$newfile){}else{warn"rename$fileto$newfilefailed:$!\n";}}和文件每个文件都被存在一个编了号的inode中,每个inode都包含一个称为计数〔linkcount〕的数字,当inode没有列在任何目录中时,计数总是0,也就是空,可以分配给文件。当inode被加到一个目录中时,计数会递增;如果此列表项被删除,计数会递减。目录包含.,也就是指向自已的inode,所以目录的计数应该总是至少为2。文件也可以不止一个列表项,如文件。在perl中用link"aa","bb"建立一个指向aa的bb。类似于在uni*shell一执行"lnaabb"。现在aa,bb都有一样的inode值,两个文件有一样的大小,一样的容。在aa中参加一行,也会在bb中参加一行。如果意外删除了aa,数据并不会丢失,可以在bb中找回来。反之也一样。但如果两个文件都删除了,则数据就会丧失。目录列表项中的规则1、一个给定的目录列表项中的inode号都指向同一个安装卷上的inode。这条规则保证,如2、果物理媒介被移到了另一台机器上,所有的目录仍和它们的文件呆在一起。这就是为什3、么可用rename把文件从一个目录移到另一个目录的原因,但两个目录必须在同一个文4、件系统〔安装卷〕中。不能用于目录。2、不能给目录起新的名字。因此目录不能用于。以上讨论的是硬,还有一个符号,也叫软,能绕过这硬连接的限制。symlink"aa","bb";orwarn"cannotsymlinkaatobb:$!";这和uni*shell中的"ln-saabb"类似。要想知道符号指向哪里,可以使用readlin函数。如果不是符号,则返回undef。两种都要以用unlink删除。建立和删除目录mkdir函数可以在一个已有的目录中建立一个目录。返回真时表示成功。mkdir"aaa",0755orwarn"cannotmakeaaadirectory:$!";第二个参数是新生成目录的权限位。以0开头,这个是一个八进制值。oct函数强制对一个字符串按八进制解释,不管前面有没有0:删除空目录,可用rmdir函数。rmdirglob"aa/*";删除aa/下所有空目录。rmdir操作符对非空目录操作会失败。所以要先用unlink删除文件,再删除目录。修改权限perl中有一个chmod函数,和uni*shell中的chmod完成类似功能。chmod0755,"aa","bb";perl中不承受符号权限表达式方式,如+*,go=u-w等。改变所有者chown函数可以改变一组文件的所有者和属组。chown1004,100,glob"*.o";可用getpwnam把用户名翻译成一个数字,用getgrnam函数把组名翻译成一个数字。改变时间戳utime函数可修改文件的访问时间和修改时间。my$now=time;my$ago=$now-24*60*60;每天的秒数utime$now,$ago,glob"*";把访问时间设为现在,修改时间设为一天以前第三个时间ctime的值在对文件做任何改变时,总被设为“现在〞,因此没方法用utime函数来设置它。因为在你设置完后它会立即被重置为“现在〞,这是因为它的主要目的就是进展增量备份:如果文件的ctime比备份磁带上的日期要新,就说明又需要备份了。使用简单的模块File::Basename模块从文件名中抽取基名,取不包括路径的文件名。通过use命令声明一个模块useFile::Basename;这样,我们就有了一个basename函数。my$name="/usr/local/bin/perl";my$basename=basename$name;得到perl该函数可用于多平台,如windows。该模块中还有一个dirname函数,它把目录名从一个完整文件名中别离出来。有选择地使用模块中的函数当你不需要模块中的所有函数,或模块中的函数和你程序中子例程有冲突时,你可以在声明模块时给模块一个引入列表,只包括需要的函数。useFile::Basenameqw/basename/;只要basename函数,不要其它函数。useFile::Basenameqw//;不要任何函数。怎么会想要一个空列表呢.这是因为,有引入只是使得我们能使用短的简单的函数名,basename,dirname。即使不引入这些名字,我们仍可以使用,只是在没有引入时,我们要用全名来调用它,如:File::Basename::dirname。每个模块都有缺省的引入列表,查相关文档有介绍。File::Spec模块用来处理文件规(filespecification)。它是一个OO的模块。用小箭头而不是::来引用函数。$newname=File::Spec->catfile($dirname,$basename);第十四章进程管理通过perl直接启动其它程序。system函数system"date";启动uni*系统的date命令。子进程会运行date命令,它将继承perl的标准输入,标准输出和标准错误。system'ls-l$HOME';注意是用单引号,因为$HOME是shell变量,否则,shell就看不到美元符号。说明要替换的符号。system"long_time_command&";把长时间运行的程序放在后台。system'foriin*;doecho==$1==;cat$i;done';可以写脚本防止shell调用system操作符时带多个参数,此时shell就不会卷入。如:system"tar","cvf",$aaa,bbb;第一个命令是tar,其余的参数会一个一个传递给它。system的退出状态基于子进程的退出状态。在uni*中0表示正常,非0表示出错。unless(system"date"){返回0表示成功print"wegaveyouadate,ok!\n";}e*ec函数与system差不多,system会生成一个子进程,e*ec是让perl进程本身去处理所要求的动作。一般用system就可以了。环境变量当你启动一个新进程时,环境变量就被继承下来了。在perl中,通过特殊的%ENV散列得到环境变量,散列中每个键表示一个环境变量。在你的程序刚开场执行时,%ENV就从父进程〔通常是shell〕继承而来。修改这个散列就改变了环境变量,它又会被新进程继承。$ENV{'PATH'}="/home/mydir/bin:$ENV{'PATH'}";设置新的环境变量,增加了一个路径delete$ENV{"IFS"};删除“IFS〞这个路径my$make_result=system"make";在新环境变量中执行程序使用反引号捕获输出当使用systemande*ec时,所启动命令的输出都被送到perl的标准输出上。有时我们需捕获这些输出。my$now=`date`;print"thetimeisnow$now.";已经有换行符,不用加\n。与shell差不多。但它把行尾去掉,而perl的输出包含\n。所以要得到同样的效果,需加上chomp操作。在列表上下文中使用反引号my$who_te*t=`who`;标量上下文,得到一个长字符串。mywho_lines=`who`;列表上下文,得到一个按行分开的数据。文件句柄形式进程perl可以启动一个处理活动状态的子进程。启动一个并发子进程的语法是把命令当做“文件名〞用在open调用中,在命令之前或之后加一个竖线,这是一个“管道〞字符,因些,这通常被称为管道翻开〔pipedopen〕。openDATE,"date|"ordie"cannotpipefromdate:$!";竖线在右边,其标准输出与文件句柄DATE连接,就像shell中的date|your_program。openMAIL,"|mailmerlyn"ordie"cannotpipetomail:$!";竖线在左边,命令的标准输入文件句柄MAIL连接,就像shell中的your_program|mail。命令启动后是个独立于perl的进程。要读取一个为读而翻开的文件句柄,我们只需进展普通的读:my$now=<DATE>;要想给进程发送数据,一人简单的“带文件句柄的打印〞就可以了:printMAIL"thetimeisnow$now.";用fork进展深入和复杂的工作用低级系统调用实现system"date";命令。defined(my$pid=fork)ordie"cannotfork:$!";unless($pid){e*ec"date";die"cannote*ecdate:$!";}waitpid($pdi.0);发送和接收信号向4201发送一个SIGINT。k

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论