设为首页 收藏本站
查看: 1021|回复: 0

[经验分享] Learning Perl 6-debugoo

[复制链接]
YunVN网友  发表于 2018-9-1 06:09:02 |阅读模式
  1.常用的Perl命令行参数
-C这个参数编译Perl程序但不会真正运行它.由此检查所有语法错误.每次修改perl程序之后我都会立刻使用它来找到任何语法错误.-w等同于use warning;-e从命令参数中的’’执行脚本,而非脚本文件-n如果需要遍历文件或者查找固定的模式,使用-n开关隐式一行一行读取文件。 常与-e连用编写类似awk的语句。SHELL>perl –ne ‘print;’ 1.txt#等同于while(){print;}SHELL>perl –ne ‘print “$.-$_”;’ 1.txt#输出行数-内容BEGIN{}, END{}块用于在循环前或者循环后执行。例如统计文件单词数:SHELL>perl –ne ‘END{print $t} @w=/(\w+)/g; $t+=@w’ 1.txt#@是匹配的模式内容(列表上下文下,每行为一个匹配的模式内容)。$t加上@w的行数即单词数。这个还可以用于其它模式数量的查找。-M 引用模块,等同于useSHELL>perl –MLWP::Simple –e ‘getstore(“www.163.com”)’;-F设置分隔符。例如/etc/passwd是以:为分隔符的。统计不同的Shell的使用人数。SHELL>perl -F':' –ane '$s{$F[6]}++;'\>;-e' END{print &quot;$_:$s{$_}&quot;for keys %s}' /etc/passwd$/,$\输入、输出分隔号。是从输入数据时,每一次读到到达这个符号就会停止。$/默认是’\n’,所以就会一行行的读取。$\是默认加到printf, print之后的字符。默认是空字符(所以print没有换行的功能)。-l使$\=$/,并chomp时自动输入分隔号。这样在print-i原位编辑。就似乎对输入文件本身修改。例如实现类似sedSHELL>perl –ipe ‘s/\bphp/\bPerl/’ file.txt2.常用的Perl特殊变量(1). $_默认的输入和模式搜索空间。while(){…} is same as while(defined($_ =  )){…}/^something/ is same as $_ =~ /^something/tr/a-z/A-Z/ is same as $_ =~ tr/a-z/A-Z/chomp is same as chomp $_其他Perl会默认使用$_的地方:各种单目函数。各种测试操作例如-f, -d。-t默认是STDIN各种列表函数print unlink各种模式匹配操作循环(2). $a, $bsort包的比较函数的特殊变量。在use strict ‘vars’时也不用声明就可以使用。在sort的比较块/函数使用时,不要用my $a定义它。(3).$num捕获的模式匹配的子模式。这些变量只读。注意/(a)(b)\1\2/中,只有$1, $2,后面的重复使用不能算\3,\4。另外,这些组的序号由左括号的顺序决定。还有一组$^n由右括号的顺序决定的对等变量。(4).$PREMATCH $`上次成功的模式匹配之前到得字符串。$MATCH $&上次成功的模式匹配到得字符串$POSTMATCH $’上次成功的模式匹配之后得到的字符串$LAST_PAREN_MATCH $+含有上次成功的匹配模式中最后的一个括号匹配的文本。当无法确定是上一次哪个匹配成功时,这个变量很有用。注意,上一次失败的匹配不会改变它们的结果。它们是只读变量 ,且仅对当前块有作用域。如果使用这些变量会导致所有模式匹配的性能降低。(5).@LAST_MATCH_START @-数组保存了当前活动的动态作用域中最近成功匹配开始时得偏移量。@-[0]为整个匹配在字符串中开始处的偏移量。@-[1]为$1开始处的偏移量,以此类推。@LAST_MATCH_END @+数组保存了当前活动的动态作用域中最近成功匹配结束处得偏移量。@+[0]为整个匹配在字符串中结束处的偏移量。@+[1]为$1结束处的偏移量,以此类推。$#+可以得到最近有多少组成功匹配。如果没有子模式匹配,则这些都为undef。对$_匹配后,$&的内容和substr $_, $-[0], $+[0] - $-[0]的内容一样。如果$num定义,则$num与substr $_, $-[n], $+[n] - $-[n]一样。$+和substr $_, $-[$#-], $+[$#-] - $-[$#-]相同。可以用$#-找到正则表达式中最后一个匹配的子组。而$#+是那次匹配时正则表达式中子组的数目。其他对等:$`substr($var, 0, $-[0]);$’substr($var, $+[0]);(6).$*将其设置为非0整数值就可以对字符串内的多行匹配。默认为undef。该变量只影响了对^$的解释。现在perl中应该用/s和/m取代他的功能。(7).$.最后读取的文件句柄的当前行号。一行指的是遇到$/的地方。默认$/为\n。关闭文件句柄会复位$.$/ $\输入,输出记录分隔符。将$/设置为整数,存有整数的标量时,perl会尝试读入字节的长度不是行。例如Local $/=32768Open my $df, $myfile or die $!;Local $_ = #读取32768个字符。(8).HANDLE->autoflush(expr), $OUTPUT_AUTOFLUSH, $|若该变量为非零值,就会强制进行刷新,并且当前选中的输出通道在打印(或者写到文件)之后都会进行刷新。默认为0.通常STDOUT是行缓冲,写到文件或其他是块缓冲。$OUTPUT_FIELD_SEPARATOR,$OFS,$,为 print 的输出域分隔符。通常 print不经任何修饰就输出它的参数,要 得到更像 awk的行为,可以将该变量设置成和 awk 的 OFS 变量一样,以指定域之间打印什么。(助记:当print语句里有“,”时会打印的东西。)IO::Handle->output_record_separator EXPR,$OUTPUT_RECORD_SEPARATOR,$ORS,$\ 为 print 的输出记录分隔符。通常 print简单地原样输出它的参数,不增加任何结尾的换行符或其他表征记录结束的字符串。要得到更像 awk的行为, 可以将该变量设同 awk 的 ORS 变量一样,以指定在 print  的结尾输出 什么。(助记:设置 $\ 而不是在 print结尾加“\n”。另外,它长得和 $/ 很像,但却是你从 Perl那里拿“回”的东西。) (译注:“回”原文为单词“back”,还指代反斜杠“backslash”,起一语双关作用。)$LIST_SEPARATOR,$&quot; 该变量同$,类似,但应用于向双引号引起的字符串(或类似的内插字符串)中内插数组和切片值的场合。默认为一个空格。$#      为打印数值时的输出格式。不建议使用 $# 变量。(9). $CHILD_ERROR$?      由最近的管道关闭、反引号(``)命令、成功调用 wait() 和 waitpid()或者 system() 操作符返回的状态信息。它就是由 wait()系统调用返回的 16 位状态字 (或是由其他信息组合而成的类似值)。因此,子进程的退出值实际上是 (&quot;$? >> 8&quot;),&quot;$? & 127&quot; 给出了导致进程结束的信号代码(如果存在),而 &quot;$? & 128&quot; 会报告是否产生了内核转储。(助记:同 sh 和 ksh类似。)在 &quot;END&quot; 子程序里,$? 含有即将交给 &quot;exit()&quot; 的值。可以在 &quot;END&quot;子程序 中修改 $? 以达到改变程序退出状态的效果。例如: END {$? = 1 if $? == 255;  # die would make it 255} (10). $OS_ERROR,$ERRNO,$!      如果按数值使用该变量,就会得到 &quot;errno&quot;变量的当前值;换句话说,如果某个系统或者库函数调用失败了,就会设置该变量。这意味着$!的值仅当 *紧接*在一个失败之后时才有意义:   $EVAL_ERROR,$@      最近一个 eval() 运算符返回的 Perl 语法错误消息。 若 $@ 是空字符串,则最近一次 eval() 进行了正确的解析和执行(  但是你所进行的操作可能已经按照通常的形式失败了)。 (助记:语法错误发生“在”哪里?)(11).$PROCESS_ID,$PID,$$运行本脚本的 Perl 的进程号。该变量应视为只读的,不过在 fork()调用 时会被改变。(助记:和 shell 一样。) Linux 用户注意:在 Linux 下, C 函数 &quot;getpid()&quot; 和 &quot;getppid()&quot;对 不同的线程返回不同的值。为了可移植,该行为没有反映在 $$里,该变量 的值在线程间保持不变。如果你想调用底层的&quot;getpid()&quot;,可以使用 CPAN 模块 &quot;Linux::Pid&quot;。$REAL_USER_ID,$UID,$< 本进程的实际 uid。(助记:如果你用了 setuid,那么这是你原来的uid。) 可以用 POSIX::setuid() 同时改变实际 uid 和有效uid。由于改变 $< 需要 进行系统调用,在更改之后应检查 $!以发现可能产生的错误。$EFFECTIVE_USER_ID,$EUID,$>  本进程的有效 uid。例:$< = $>; #set real to effective uid($) = ($>,$后需要检查$!以发现可能产生的错误。(即如果你用了 setuid,那么这是你要变成的 uid。)       $REAL_GROUP_ID, $GID,$( 本进程的实际gid。如果你使用的机器支持同时属于多个组,则该变量给出的是被空格隔开的所在组列表。第一个数值是由 getgid()返回的结果,后续的内容 是 getgroups()返回的结果,其中可能有和第一个值相同的项。然而为了设置实际 gid,赋给 $( 的必须是单个数值。因此从 $( 得到的值在没有强制为数值(例如同零相加)的情况下*不应*再赋给 $(。可以用 POSIX::setgid() 同时改变实际 gid 和有效 gid。更改 $(. 后需要检查 $! 以便发现可能出现的错误           $EFFECTIVE_GROUP_ID,$EGID,$)      本进程的有效 gid。如果你使用的机器支持同时属于多个组,则该变量给出的是被 空格隔开的所在组列表。第一个数值为 getegid()的返回值,后续的值是 getgroups()的返回值,其中可能有和第一个值相同的项。类似地,赋给 $) 的值也必须是一个空格隔开的数值列表。第一个数设置有效  gid,其余部分(若存在)则传给 setgroups()。要达到向 setgroups()传递空列表 的效果,只需重复一遍新设置的有效 gid;例如,要将有效  gid 强制为 5 并向 setgroups() 传入空列表,就要这么写:&quot; $) = &quot;5  5&quot; &quot;。可以用 POSIX::setgid() 同时改变有效 gid 和实际 gid  (只用单个数值参数)。 更改 $) 后需要对 $!进行检查以便发现可能出现的错误。            $、$( 和 $) 只能在支持对应的 *set[re][ug]id()*   例程的机器上进行设置。$( 和 $) 只能在支持 setregid() 的机器上互换。    $PROGRAM_NAME,$0      包含当前运行程序名。在一些(注意:不是全部)操作系统下,向 $0 赋值可以改变 &quot;ps&quot; 程序所看到 的参数域。某些平台上你可能需要用特殊的 &quot;ps&quot; 选项或其他的 &quot;ps&quot; 才能看到 这个改变。修改 $0 作为指示当前程序状态的一种方法,要比用来隐藏你在运行的程序更有用。(助记:同 sh 和 ksh 一样。)  注意 $0的最大长度受相关平台的限制。多数极端情况下可能被限制在原始的 $0所占据的空间之内。  在某些平台上可能会附加一些填充字符(例如空格)在 &quot;ps&quot;  显示出的修改名 之后。有些平台上这种填充会充满原参数域,并且不受你的控制(例如Linux 2.2)。    (12).$OSNAME,$^O为当前 Perl副本编译时所处的操作系统名称,在配置过程中即确定。其值同$Config{'osname'} 相同。另见 Config 及 perlrun 中说明的 -V命令行开关。    (13).$ARGV 当读取时包含当前文件名。 @ARGV 数组@ARGV含有脚本的命令行参数。 $#ARGV 通常是参数数量减 1,因为$ARGV[0]是第一个参数,而*不是*程序本身的命令名称。命令名称请见$0。    (14).在某个函数内,数组@_包含传递给该函数的所有参数。    (15).@INC 数组@INC 包含一个路径列表,&quot;do EXPR&quot;、&quot;require&quot; 和 &quot;use&quot;结构都会在该列表中查找自己 所需的库文件。它的初始值由所有 -I命令行开关的参数、默认 Perl 库目录(如 /usr/local/lib/perl)和代表当前目录的“.”依次组合而成。(当使用 &quot;-T&quot; 或 &quot;-t&quot; 开启污染检查开启时则不会把“.”附加在后面。)若需要在运行时修改该变量,你应该使用 &quot;use lib&quot;指示符,以便能正确载入平台相关的库:    use lib '/mypath/libdir/';     use SomeMod;你还可以直接在 @INC 中放入 Perl代码,以达到在文件包含系统中插入拦截点的目的。这些拦截点可以是函数引用、数组引用或 bless 过的对象。%INC 散列表 %INC 含有若干项,每一项都代表由 &quot;do&quot;、&quot;require&quot; 和 &quot;use&quot;运算符包含进来的一个文件。散列键是包含处给定的文件名(模块名已转换为路径名),散列值为找到该文件的位置。 &quot;require&quot;运算符用这个散列表判断某个特定文件是否已经被包含过。    (16).%ENV,$ENV{expr}散列表%ENV含有当前的环境。对 &quot;ENV&quot; 设置值会改变后续 fork()出来的所有子进程的环境。    (17).%SIG,$SIG{expr}  散列表 %SIG 包含信号对应的处理器。例如:sub handler {       # 第一个参数是信号名称my($sig) = @_;print &quot;Caught a SIG$sig--shutting down\n&quot;;close(LOG);exit(0);}         $SIG{'INT'}  = \&handler;$SIG{'QUIT'} = \&handler;                 ...$SIG{'INT'}  = 'DEFAULT';   # 恢复默认行为$SIG{'QUIT'} = 'IGNORE';    # 忽略 SIGQUIT    设置为 'IGNORE' 值通常具有忽略该信号的效果,除了 &quot;CHLD&quot;信号以外。用 %SIG散列表也可以设置特定的内部拦截点。在即将打印一条警告信息时,由$SIG{__WARN__}、指定的例程会被调用。警告信息作为第一个参数被传递给该例程。__WARN、拦截点的存在会消除通常 要打印到 STDERR、上的警告。你可以利用这一点将警告保存到变量里,或者像这样将警告转、 变为致命错误:local $SIG{__WARN__} = sub { die $_[0] };eval $proggie;eval当抛出一个致命异常时,由 $SIG{__DIE__}指定的例程会被调用。当__DIE__拦截例程返回后,异常处理会像拦截点不存在一样继续进行。除非拦截例、程 本身通过 &quot;goto&quot;、循环退出或 die() 的方式结束。&quot;__DIE__&quot;、处理器在调用过程中被显式关闭,因此你可以在 &quot;__DIE__&quot;、处理器中继续 die。&quot;__WARN__&quot; 也具有类似行为。     (18).错误指示器$@ $! $^E $?分别对应Perl解释器, C库,操作系统和外部程序检测到得错误。为了展示这些变量之间的区别,请考虑以下这个使用了单引号引起字符串的 Perl表达式: eval q{        open my $pipe, &quot;/cdrom/install |&quot; or die $!;        my @res = ;close $pipe or die &quot;bad pipe: $?, $!&quot;;};当这条语句执行之后,4 个变量都有可能被设置。在需要 &quot;eval&quot; 的字符串没有通过编译(若 &quot;open&quot; 或 &quot;close&quot;导入的原型错误则可能发生)或者 Perl 代码在执行过程中 die() 掉,则 $@变量会被设置。这些情况下 $@ 的值是编译错误信息或 &quot;die&quot; 的参数(其中会内插 $! 和 $?)。(另见 Fatal。)上面的 eval() 表达式执行后,open()、&quot;&quot; 和 &quot;close&quot; 被翻译成对 C运行库的调用,继而进入操作系统内核。若其中某个调用失败,则 $! 会设置为C 库的 &quot;errno&quot; 值。在少数操作系统下,$^E 可能含有更详细的错误指示,例如“CDROM仓门没有关闭”。不支持扩展错误 信息的系统只是将 $^E 设置为和 $!一样的值。最后,$? 在外部程序 /cdrom/install 失败时设置为非 0 值。高 8位反映出该程序遇到的特定错误 条件(程序的 exit() 值),低 8位反映失败方式,例如信号致死或核心转储,细节参见 wait(2)。对比仅在检测到错误条件时才设置的 $! 和 $^E,变量 $? 在每个 &quot;wait&quot; 或管道&quot;close&quot; 时都会 设置并冲掉旧值。这一行为更接近 $@,后者在每次 eval()后总是在失败时设置并在成功时清除。 3.Perl中Use和require的区别区别一:跟require不同的是,use只能用于模块的包含,也就是.pm文件。比如:use  MyDirectory::MyModule;实际上,编译器将从@INC指定的目录下去寻找MyModule.pm模块。如果模块名称中包含::双冒号,该双冒号将作为路径分隔符,相当于Unix下的/。编译器将从@INC指定的每个目录下的MyDirectory子目录去寻找MyModule模块区别二:两个都是包含,但是包含的条件是不一样的。require包含是发生在程序运行期,而use包含是发生在编译期。学过C/C++的人比较容易理解。下面的例子是错误的:use Config;if( $Config{'osname'} eq &quot;MSWin32&quot; ) { use Win32Module; } else{ use UnixModule; }正 因为use是发生在编译期,代码没有执行,所以$Config变量的值是无法判断的。在内部,use其实调用了require和import静态函数。 import()函数告诉包哪些特征将要被导入当前包中,这意味着用之前不必验证函数或者变量是否合法。而require是不会调用import()的。   参考/转载:Perl by example. Third edition[精华] 【Perl 文档中文化计划】Perl 特殊变量翻译完成http://www.chinaunix.net/jh/25/769567.html在Perl中Require 和 use 的区别 http://blog.csdn.net/EagleYIN417/archive/2009/04/07/4053613.aspx

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-560094-1-1.html 上篇帖子: Perl轻松分析数据两例 下篇帖子: perl snmp rrdtool 画图
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表