perl教程012

perl教程012 - 下载...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: 下载 第12 学时 使用 Perl的命令行工具 到现在为止, Perl一直只是一个非常简单的解释程序。你将一个程序键入一个文件,然后 调用 Perl解释程序,以便运行你的程序。不过 Perl解释程序比这个程序灵活得多。 Perl解释程序中内置了一个调试程序。使用该调试程序,可以像播放录像带那样运行你的 Perl程序。可以将程序倒到开头,使它慢速运行,也可以快速运行,还可以将它定格,以仔细 观察程序的内部结构。在查找 Perl 程序中存在的问题时,调试程序常常是个使用得很不充分的 工具。 Perl也能运行不是键入文件的程序。例如,可以直接从系统的命令提示符处运行一些小程 序。 在本学时中,你将要学习: • 如何使用 Perl的调试程序。 • 如何使用命令行开关来编写 Perl程序。 12.1 什么是调试程序 P e r l 调试程序是个 P e r l解释程序的内置特性。它使你能够取出任何一个 P e r l 程序,然后逐 个语句运行该程序。在运行过程中,你可以查看各个变量,修改这些变量,让程序运行较长 的时间,中断程序的运行,或者从头开始运行该程序。 从你的程序角度来看,它与普通程序并无区别。输入仍然来自键盘,输出仍然送往屏幕。 程序并不知道何时停止运行,何时它正在运行。实际上,你可以观察程序的运行情况,根本 不必中断程序的运行。 12.1.1 启动调试程序 若要启动 Perl调试程序,必须打开操作系统的命令提示符。如果你是 DOS和Windows用户, 那么要打开 MS-DOS的标准提示符 C:\ 。如果是 UNIX用户,这个提示符应该是你登录时显示的 提示符(通常是%或$) 。 对于运行 P e r l的M a c i n t o s h用户来说,只需从 S c r i p t菜单中选定 D e b u g g e r 。这时就会为你打 开带有提示符的 Debugger窗口。 本节中的所有代码例子均使用第 9 学时的程序清单 9 - 2 中的 E m p l o y e e 程序。你会发现可以 很容易将一个书签放在这一页上,然后前后翻阅,查找你想要的信息。若要在提示符处启动 调试程序(本例中使用 DOS提示符) ,请键入下面这行命令: P e r l的 - d 开关可使 P e r l以调试方式启动运行。命令行上也指明了被调试的程序。然后显示 关于版本信息的某些消息,如下所示: 138 使用第二部分 高 级 特 性 下载 该调试程序首先显示版本号( 1.0401 ,你的版本号可能不一样)和 help ( 帮助 )提示。接着 显示该程序的第一行可执行代码。由于第一个语句实际上包含 7行,从“ my @employees= (” 开始,以“);”为结尾,因此所有 7 行语句均显示一个描述,以说明它们来自什么文件 (Employee ) ,以及它们是在文件的哪一行或哪几行上找到的(第 5至第 11行) 。 最后,你看到调试文件的提示符 D B < 1 >。1 表示调试文件正在等待它的第一个命令。调试 程序提示符后面的光标正等待你输入命令。 这时,你的 Perl程序实际上暂停在第一个指令 -my @employees=(的前面。每当调试程序向 你显示程序中的一个语句时,它就是准备要执行的语句,而不是上一个运行的语句。 现在调试程序已经作好准备,等待你输入命令。 12.1.2 调试程序的基本命令 输入调试程序的第一个和最重要的命令是 help(帮助)命令。如果在调试程序的提示符处 键入 h ,那么调试程序的所有可用命令均被输出。也可以使用该命令的某种变形,如 h h ,它 能输出命令和语句的汇总, h cmd 用于输出某个命令的帮助信息。 帮助命令的列表也许比较长,一个屏幕显示不下,开头的几个命令显示后,就需要向下 滚动。若要每次显示一屏调试命令,可以在命令的前面加上一个 |字符。因此,如果想每次查 看一屏帮助命令,请使用命令 |h。 调试程序的最常用特性是每次运行一个 Perl代码的指令。因此,如果继续使用上面的例子, 若要转至你的 Perl 程序的下一个语句,可以使用调试程序的命令 n: 当你键入命令 n 后, P e r l 就执行 E m p l o y e e程序的第 5 至11 行语句。然后调试程序输出要执 行的下一个语句(但尚未运行) my($L1,$F1)=split(’ ’ $a );并显示另一个提示符。 ,, 当程序运行到这个时候, @ e m p l o y e e s被初始化为 5个名字和工资等。若要查看这些信息, 可以将它们输出: 实际上, P e r l的任何语句都可以在调试程序提示符后面运行。请注意,来自 @ e m p l o y e e s 的数组元素都是一道运行的。可以输入下面的命令,以便很好地将它们输出: 下载 139 第12学时 使用Perl的命令行工具使用 若要继续运行该程序,只需不断键入 n,如下所示: 显然,调试程序将该程序倒退到这个位置,第 2 3 行准备再次运行。 P e r l 的s o r t 语句实际上 是个循环,调试程序逐步通过 s o r t 代码块中的每个语句。如果你不断键入 n ,那么调试程序将 不断循环运行,直到 sort运行结束,这需要花费一定的时间。 若要重复运行上面的命令,也可以在调试程序的提示符处按 Enter键。 12.1.3 断点 如果不是每次执行一个指令,逐步执行该程序,你也可以让调试程序连续运行你的 Perl程 序,直到到达某个语句,然后停止运行。这些停止运行的位置称为断点。 若要设置断点,必须在程序中选定一个要停止运行的位置。命令 l 用于列出程序的下面 1 0 行。再次键 l ,可以列出下面的 1 0 行,如此类推。若要列出从某一行开始的程序,请键入 l lineno,其中 lineno是程序的行号。也可以设定要列出的行的范围,方法是键入命令 l start-end。 在程序清单中,标号 = = = > 用于指明调试程序准备执行的当前行,请看下面的代码: 在这个例子中,第 3 3行是设置断点的好位置。它位于 s o r t语句的后面,并且它是程序的主 循环中的第一个语句。你可以在 Perl 程序中的任何位置上设置断点,只要这个断点是个有效的 P e r l 语句。但是断点不能设置在花括号(第 3 0行) 、标点符号(第 2 9行) 、空行(第 3 1 行)或 只包含注释的代码行上。 若要设置断点,请使用 b breakpoint 命令,其中 b r e a k p o i n t可以是行号或子例程名。例如, 140 使用第二部分 高 级 特 性 下载 若要在第 33行上设置断点,可以输入下面这个命令: 必须知道的另一个关于断点的命令是继续命令 c。命令 c向调试程序发出指令,使 P e r l程序 运行到下一个断点或程序的结尾: 在这个代码中,调试程序按照要求使 Perl程序停止在第 33行上,print-emp函数被调用之前。 断点仍然可以设置,因此,键入另一个 c子句,可使程序继续运行 p r i n t _ e m p ( )函数,并且再次 停止在第 33行上: “下一个”指令的命令 若要查看你在程序中已经设置的断点,可以像下面这样使用命令 L: print_emp ( ) 的输出 待运行的下一行代码 这个例子显示了调试程序有一个断点,在文件 Employee中的第 33行上。 若要撤消程序中的断点,可以采用设置断点时的相同方法使用命令 d ,比如 d line 或 d subname : 12.1.4 其他调试程序命令 如果想查看 print-emp()函数的运行情况,可以用若干不同的方法来执行这项操作。首先使 用命令 R ,重新启动你的程序: 下载 141 第12学时 使用Perl的命令行工具使用 命令 R用于使 P e r l 程序回到它的开始处,准备再次执行该程序。你已经设置的断点保持已 设置状态, Perl程序中的所有变量均复位。在上面这个代码中,断点设置在第 33行上。这时可 用下的命令继续运行该程序: 如果执行命令 n,就可以执行下面的指令: 但是,如果用这种方法逐步执行该程序,你就无法查看 print-emp()中究竟有什么。若要单 步进入 print-emp(),不要使用命令 n,而应该使用命令 s,即单步执行命令。 s命令与 n命令的作 用很相似,不过 s命令并不仅仅执行函数,然后转入下一个指令,而是执行函数,然后在函数 中的第 1个指令处停止运行,如你在下面看到的情况一样: 在这里,显示了 p r i n t _ e m p ( ) 的第 1 个语句。也可以用 b print_emp 设置一个断点,在 print_emp()中停止运行。现在可以继续运行该程序,使用命令 n逐步通过该函数,如下所示: 还可以在 P e r l程序运行时修改程序里的变量。例如,若要给员工每小时临时增加 2 . 5 0美元 的工资,可以输入下面的代码: 在上面的代码段中,变量 $ h o u r l y 被输出( 1 0 . 1 5 ) ,并增加 2 . 5 0 ,然后程序继续运行。 Printf语句输出 $hourly 的新值。 最后,若要退出调试程序,只需在调试程序提示符处键入 q。 12.2 练习:查找错误 这个练习向你展示如何使用调试程序来查找程序中的错误。程序清单 1 2 - 1中的程序存在 142 使用第二部分 高 级 特 性 下载 一个问题(实际上是两个问题) 。它应该输出下面这些消息: 但是它并没有输出这些消息。你的任务是键入程序清单 1 2 - 1 中的程序,并没法找出里面 的错误。这些错误都不属于语句问题, P e r l的警告特性没有被激活,同时, use strict 没有输出 任何消息,不过调试程序应该使得错误可以非常容易地被找到。 当你键入程序后,用调试程序运行 Perl,以便设法找到错误。请记住,要经常输出有关的 变量和表达式,并单步通过各个函数调用,每次调用一个函数。 程序清单 12-1 Buggy 程序 这个问题的解决办法请参见本学时结尾处的“思考题” 。 12.3 其他命令行特性 调试程序并不是 Perl解释程序中可以用命令行开关激活的惟一特性。实际上,许多非常有 用的 Perl程序都可以在命令行提示符处编写。 M a c i n t o s h 用户应该通过 S c r i p t 菜单来运行这些命令行代码,方法是选定 l-liners,然后将命令键入对话框。 12.3.1 单命令行程序(One-Liners) 这种程序的关键是在命令行上赋予 P e r l 的- e 开关。 - e的后面可以是任何 P e r l语句,如下例 所示: 你可以使用多个 -e开关来插入多个语句,或者用分号将这些语句隔开,如下所示: 下载 143 第12学时 使用Perl的命令行工具使用 应该注意的是,大多数命令解释程序都规定了引号的使用规则。 Wi n d o w s / D O S 命令解释 程序( c o m m a n d . c o m或N T的命令 S h e l l)允许你使用双引号将单词括起来,比如上例中的 p r i n t 和 Hello Wo r l d ,但是不能随意将双引号放入别的双引号中,也不能随意将 >、 < 、 |或 ^等符号 放入双引号中。关于 DOS/Windows中引号的详细使用规则,请查看你的操作系统手册。 在U N I X下,一般来说,只要引号配对,即每个开引号有一个闭引号,并且嵌入的引号前 面有一个反斜杠 \,那么你的代码就没有问题: 上面这个代码在大多数 UNIX shell(csh 、 k s h 、b a s h 等) 下均能运行,并能输出带有正确换 行符的消息。若要了解你的 shell的引号使用规则的完整列表,请查看 shell的在线手册页。 - e开关的一个经常的非常有用的用法是与 - d组合起来使用,并将它直接放入 P e r l 的调试程 序中,但是没有需要调试的程序: 这时,调试程序就等待你输入命令了。这种特殊的开关并置方法可以用来测试 P e r l语句, 而你不必编写完整的程序。然后再进行测试、调试、编辑、再测试和再调。你只需要在调 试程序中运行你的语句,直到它能够运行为止。命令行上的 1 是指最起码的 P e r l 程序,它是计 算为 1并且返回 1的一个表达式。 12.3.2 其他开关 P e r l解释程序中的 - c开关可供 P e r l 用来查看你的代码,以便找出语句上的问题,但是它实 际上并不运行程序: 如果出现语句错误, Perl就会输出下面这样一条消息: 与-w组合起来后, -c开关就能对你的程序进行编译,然后显示 Perl认为适当的警告消息。 当你向知识更丰富的 Perl用户或系统管理员了解调试代码的情况时,常常必须提供正在使 用的 P e r l解释程序的版本。目前正在使用的 P e r l 语言的主要版本是 Perl 5 。该解释程序本身有 一个可以查看的版本,你可以在命令行上使用开关 -v ,便可了解该版本号,如下如示: 144 使用第二部分 高 级 特 性 下载 在上面这个代码中, P e r l 解释程序的版本是 5 . 0 0 4 _ 0 2。若要了解更加详细的信息,比如该 解释程序是如何创建的,何时创建的,等等,可以运行带有 -v 开关的解释程序,如下所示: 如果你试图查找 Perl解释程序本身的某个问题,比如安装时出现的一个问题,那么上面这 个输出可能对你有用。在这个输出的结尾处,请注意 @ I N C 的各个值。这个特定安装的 P e r l希 望在这些目录中找到它的各个模块。当 Perl安装后,它不能简单地从一个目录移动到另一个目 录。该解释程序本身对于何处能找到它的各个模块有一个内置的思路,如果改变这个思路, 就会导致 Perl 到错误的地方去查找它的模块。关于模块的问题,将在第 14学时中详细介绍。 12.3.3 空的尖括号与更多的单命令行程序 迄今为止介绍的尖括号运算符( < > )具有两个功能: 1) 如果尖括号中间是文件句柄,尖括号运算符允许你读取文件句柄,比如 <STDIN>。 2) 如 果尖括号中间是搜索模式,尖括号运算符能返回与该模式匹配的文件列表,这称为 一个 glob,比如 <*.bat>。 尖括号运算符还有另一个功能。一组尖括号运算符如果中间没有任何东西,那么它可以 读取命令行上所有文件的内容;如果没有给出文件名,则可以读取标准输出。有时空尖括号 运算符称为菱形运算符(因其形状而得名) 。例如,请看下面这个小型 Perl程序: 如果将上面的程序保存为 Example.pl,那么用下面这个命令行运行该程序: 就可使运算符 < >读取 f i l e 1 的内容,每次读 1 行,然后读取 f i l e 2,接着读取 f i l e 3。如果没有 设定文件,则尖括号运算符从文件句柄 S T D I N中读取数据。这个运行特性类似 U N I X 实用程序 Sed、awk等的特性,如果命令行上设定了文件,则从文件中读取输入,否则读取标准输入。 P e r l 程序的参数,即去掉 P e r l 的参数 - w、 - c 、 - d和 - e 之后,将被存放在称 为@ A R G V的数组中。例如,对于上面这个代码段的参数, $ A R G V [ 0 ]将包含 file1,$ARGV[1]包含 fole2,如此等等。 Perl程序的 -n开关可用于将任何 -e 语句封装在该小程序中: 145 第12学时 使用Perl的命令行工具使用 下载 因 此,如果要创建一个简短的单命令行程序,从输入数据中删除前导空格,你可以编写 下面的命令: 上面这个命令实际上运行类似下面这个 Perl程序: 在上面这个代码段中,名字为 f i l e 1的文件被打开,并被赋予 w h i l e 循环中的 $ _ ,每次 1 行。 该行用 S/^\S+//g进行编辑,然后进行输出。 -p与-n 开关的作用相同,差别在于语句执行后各个 文件行便自动输出。因此,重新编写上面这个命令行便产生下面这个命令行: 当你用 Perl的单命令行程序来编辑一个文件时,必须注意不要在打开文件进行读取操作的 同,又试图对它进行写入操作,像下面这个例子那样: 上面这个代码段试图从称为 d o s f i l e的文件中删除回车符。问题是在 P e r l命令被处理之前, d o s f i l e 文件已经被 > d o s f i l e 改写。编辑文件的正确方法应该是将输入重定向到另一个文件中, 并将文件改为它的原始名字,如下所示: 有些 P e r l爱好者认为,编写简短的“单命令行程序( o n e - l i n e r s ) ”只不过 是一种娱乐。他们认为,程序越复杂,功能越多,就越好。 Perl Journal 是介 绍Perl的一份季刊,它在每一期上刊登了许多单命令行程序。 12.4 课时小结 在本学时中,我们介绍了如何有效地使用调试程序来查找 Perl程序中存在的问题;介绍了 尖括号运算符( < > )的另一个功能,它使 P e r l能够处理命令行上的所有文件;另外,还介绍 了如何使用 Perl 解释程序的 -n和-p开关,来编写小型单行 Perl 程序。 12.5 课外作业 12.5.1 专家答疑 问题: 我真的希望 Perl有一个图形调试程序。是否存在这样的东西? 解答: 是的,有几个这样的调试程序。如果你在 Wi n d o w s 下使用 P e r l, A c t i v e s t a t e拥有很 好的图形调试程序。 问题: 调试程序不断输出的 main: :究竟是个什么东西? 146 使用第二部分 高 级 特 性 下载 解答: 它与 Perl的程序包命名约定有关。它的一些情况将在下一个学时中介绍,因此现在 你不必对它考虑太多。 问题: Perl是否还有别的命令行开关? 解答: 是的,还有一些。你可通过在线手册查看这些开关的完整列表。若要访问这些信 息,请在命令提示符处键入 perldoc perlrun 。 12.5.2 思考题 1) 程序清单 12-1中存在哪些错误? 2) 如果命令行上没有给定文件,那么读取 <>时将返回 a. undef。 b. 来自标准输入的数据行。 c. True。 3) Prel 调试程序执行时能够输出 P r e l 语句,这称为跟踪方式。你如何使调试程序进入跟踪 方式呢?(提示:必须查看调试程序的帮助消息,才能回答这个问题。 ) a. 使用 T命令,使之进入跟踪方式。 b. 使用 t 命令,使之进入跟踪方式。 12.5.3 解答 1) 首先,在第 15行中,范围( 20..0)无效。范围运算符“ ..”不应该是降序,而应该是升 序。这一行应该改为 f o r ($ _ = 2 0 ;$ _ > - 1; $ _ -)循环,将范围倒过来( 0 . . 2 0) ,或者使用类似 的范围。其次,在第 1 0 行上, $ m e s s = s / g l a s s e s / g l a s s /看上去像是对 $ m e s s 的替换表达式,但实 际上并非如此。替换实际上是对 $_进行的,因为赋值运算符( = )应该是个连接运算符( =~) 。 2) 答案是 b。如果没有给定文件名,那么 <>便开始读取 STDIN。 3) 答案是 b。t命令能够在程序执行时输出程序的所有语句。 T命令用于输出堆栈跟踪记录, 这是当前正在执行的函数、调用该函数的函数等的列表。 ...
View Full Document

Ask a homework question - tutors are online