开元周游
德国频道
查看: 3952|回复: 11
打印 上一主题 下一主题

Linux编程入门之 脚本编程

[复制链接]
1#
发表于 28.11.2002 11:44:13 | 只看该作者
                       Linux编程入门之 脚本编程 <br>整体思路<br>本讲是编程系列讲座的第二讲,主要讲述 Linux 平台上的两种最常用的脚本编程语言,即 BASH 和 PERL。由于 Linux 是以 UNIX 设计思想为蓝本逐步演化发展而来的,因此在 Linux 环境中命令行操作和文本处理就明显要多于 Windows 系统,故而脚本语言以其简洁、快速、方便的特点在 Linux 系统中得到广泛应用。BASH 现在几乎是各种 Linux 发行版中 Shell 的事实上的标准,掌握BASH可以帮助用户更为便捷、合理的理解、管理和使用 Linux 系统,即使你不用 BASH 编程,掌握 BASH 对你理解整个系统也是必不可少和大有裨益的;PERL诚然是一种非常适合写 CGI 程序的语言,但是PERL的作用不仅仅如此,掌握PERL如同找到了 Linux 编程的捷径,有许多 Linux 下的好东西就是用 PERL 完成的,比如 Majordom(一个中量级邮件列表程序)。本讲的目的是通过介绍 Linux 上这两种主流脚本语言编程的知识,使大家找到脚本语言的共性,掌握这两种脚本语言的使用,并触类旁通的理解其他脚本语言,迅速引导有一定 Linux 使用经验的同学入门,更好的把握 Linux 系统和使用 Linux。<br><br><br>本讲首先对 Linux 上的脚本编程做一个简单介绍;然后通过分别讲解 BASH 和 PERL 这两种重要的脚本编程环境,并结合具体实例演示来使大家对 Linux 上的脚本编程有一个感性认识,获得这种编程思想的基本思路。由于时间有限,许多细节问题我们只在讲义中给出解释,而不作细致讲解,希望本次讲座能给大家一个解决问题的思路和总体把握尺度,更多的探索留待大家自己课后去钻研。 <br><br><br>--------------------------------------------------------------------------------<br><br>主要内容<br> BASH 部分 <br> BASH 的历史和概貌<br><br> BASH 的基本语法<br><br> BASH 中的特殊保留字<br><br> BASH 的其他高级问题<br><br> PERL 部分 <br> Perl 的特点、历史和许可证<br><br> 用 Perl 写 CGI 入门<br><br> Perl 的变量<br><br> Perl 的简单语法(与C语言语法的异同)<br><br> Perl 中的的正则表达式<br><br> 一些 Perl 的实际运用范列<br><br><br>--------------------------------------------------------------------------------<br><br>各部分要点<br> BASH 的历史和概貌 <br><br>BASH 是什么的缩写 <br>Linux 的其他 Shell <br>BASH 的主要特点 <br><br> BASH 的基本语法<br><br>最简单的例子 —— Hello World&#33; <br>关于输入、输出和错误输出 <br>BASH 中对变量的规定(与C的异同) <br>BASH 中的基本流程控制语法 <br>函数的使用 <br><br> BASH 中的特殊保留字<br><br>保留变量 <br>随机数<br>运算符 <br>变量的特殊操作<br><br><br> BASH 的其他高级问题<br><br>BASH 中的返回值处理 <br>关于用 BASH 设计简单用户界面 <br>在 BASH 中读取用户输入问题 <br>一些特殊的惯用法 <br>BASH 程序的调试 <br>关于 BASH2 <br><br> Perl 的特点、历史和许可证<br><br>erl 的基本特点 <br>erl 的历史 <br>erl 的使用许可证 <br><br> 用 Perl 写 CGI 入门<br><br>为什么要用 Perl 来写 CGI <br>几个简单的 Perl CGI 程序 <br>CGI 中常用的环境变量 <br>关于 CGI 的更多内容<br><br> Perl 的变量<br><br>简单变量 <br>数组 <br>关联数组 <br>各种运算符汇总 <br><br> Perl 的简单语法(与C语言语法的异同)<br><br>基本输入输出 <br>分支循环控制结构 <br>函数 <br>常用系统调用 <br>文件操作 <br>进程管理 <br><br> Perl 中的的正则表达式<br><br>正则表达式的三种形式 <br>正则表达式中的常用模式 <br>正则表达式的 8 大原则 <br><br> 一些 Perl 的实际运用范列<br><br>Majordomo 邮件列表程序 <br>TurningBot 项目 <br>简单站内搜索引擎 <br><br>练习<br>请用 BASH 编写一个小程序,实现在指定目录下递归搜索有特定后缀名的文件,并更改其后缀。 <br>用 BASH 编写一个具有类似特洛伊木马功能的小程序。 <br>分析讲义中自代的站内搜索程序的 Perl 源代码,为其添加你想到的新功能。 <br>用 Perl 语言编写一个留言本 CGI 程序。 <br>用 Perl 语言编写一个统计 Apache Log 文件中信息的程序,统计哪些 IP 喜欢访问哪些页面? <br>用 Perl 语言编写一个在大段文字中匹配查找所有以 &quot;m&quot; 开头,以 &quot;g&quot; 结尾中间含有 &quot;o&quot; 的单词。 <br>推荐书目<br>BASH Programming - Introduction HOW-TO,by Mike G mikkey at dynamo.com.ar <br>Advanced Bash-Scripting HOWTO - BASH 脚本编程指南,by Mendel Cooper(thegrendel@theriver.com)<br>(中译) <br>Learning Perl 入门读物,适合入门者使用。<br>(中译) <br>rogramming Perl 推崇备至的经典书籍,也就是所谓的Camel Book,适合想深入了解perl的人阅读。<br>(中译) <br>erl Cook Book 正如烹饪书一样,它适合随机阅读,也可在需要时查阅,但是读完它也很有好处。本书介绍了许多有效的“菜谱”,可以节省你的时间,提高程序效率。 <br>Perl 5 从入门到精通 介绍得还算比较详细,不过翻译的不好。 <br>&lt;&lt;Perl入门&gt;&gt; 电子工业出版社 <br>反馈<br>本讲由陶品讲解。欢迎任何意见和建议,可发 email: taopin@sina.com 与陶品联系。 <br><br>AKA 自由软件系列讲座                       
2#
 楼主| 发表于 28.11.2002 11:44:44 | 只看该作者
                         <br>1    BASH 的历史和概貌<br>BASH 是什么的缩写 <br><br>Linux 中的其他 Shell <br><br>BASH 的主要特点 <br><br>为什么要学习 BASH 编程呢?因为 BASH 是每个 Linux 发行版都带有的一个标准基础软件,所以学会在 BASH 下编制一些小程序就可以让你对 Linux 系统的管理应付自如;其次 BASH 非常简单,如果不深究 BASH 语法中的细节的话,你可以用 1 个小时就学会他,应该说 BASH 比 HTML 要更容易学;最后即使你不打算用 BASH 编程,但是 Linux 系统中的许多配置文件和脚本都是 BASH 的语法,不懂一点 BASH 的知识就不能很好的理解和使用 Linux 。其实最简单的 BASH 就和 DOS 下的批处理文件类似,只要把要执行的命令一行一行写出来就行。<br><br><br><br><br>1.1    BASH 是什么的缩写<br>BASH = GNU Bourne-Again SHell,BASH 是 GNU 组织开发和推广的一个项目,不过也有一种风趣的说法认为 BASH = Born-Again Shell。<br><br>BASH 是 Linux 操作系统上的一个 Shell,是由 /bin/bash 解释执行的。BASH 支持 IEEE POSIX P1003.2/ISO 9945.2 脚本语言工具标准。<br><br><br><br>1.2    Linux 系统中的其他 Shell<br>Shell 的概念是从 UNIX 系统中引用过来的,在 Linux 和 UNIX 系统里现在存在这多种不同的 Shell 可以使用。最常用的几种是 <br><br>Bourne shell (sh) <br>C shell (csh) <br>Korn shell (ksh)<br><br>三种shell 都有它们的优点和缺点:<br><br>Bourne shell 的作者是 Steven Bourne,它是 UNIX 最初使用的 Shell 并且在每种 UNIX 上都可以使用。Bourne Shell 在 Shell 编程方面相当优秀,但在处理与用户的交互方面作得不如其他几种 Shell; <br><br>C Shell 由 Bill Joy 所写,它更多的考虑了用户界面的友好性,支持象命令补齐(command-line completion)等一些 Bourne Shell 所不支持的特性,普遍认为C shell 的编程接口做的不如 Bourne Shell,但 C Shell 还是被很多 C 程序员使用,因为 C Shell 的语法和 C 语言很相似,这也是 C Shell 名称的由来; <br><br>Korn Shell (ksh) 由 Dave Korn 所写,它集合了 C Shell 和 Bourne Shell 的优点并且和 Bourne Shell 完全兼容。 <br><br>除了这些 Shell 以外,许多其他的 Shell 程序吸收了这些原来的 Shell 程序的优点而成为新的 Shell 。在 Linux 上常见的有 tcsh (csh 的扩展),Bourne Again shell(bash, sh 的扩展), 和Public Domain Korn shell (pdksh, ksh 的扩展)。<br><br>BASH 是大多数 Linux 系统的缺省 Shell。 BASH 只是 Linux 操作系统上的一种 Shell,虽然他是一个比较优秀和主流的 Shell,但是针对不同用户的不同需要和喜好,在 Linux 操作系统上还有几种其他的 Shell,如:ksh、csh、zsh 等。<br><br><br>1.3    BASH 的主要特点<br>Bourne Again shell (bash), 正如它的名字所暗示的,是 Bourne shell 的扩展。BASH 与 Bourne shell 完全向后兼容,并且在 Bourne shell 的基础上增加和增强了很多特性。BASH 也包含了很多 csh 和 Korn Shell 里的优点,使得 BASH 有很灵活和强大的编程接口,同时又有很友好的用户界面。为什么要用 BASH 来代替 sh 呢?Bourne Shell 最大的缺点在于它处理用户的输入方面,在 Bourne shell 里键入命令会很麻烦,尤其当你键入很多相似的命令时,而 BASH 准备了几种特性使命令的输入变得更容易。 BASH 的新功能包括 命令补齐、通配符、命令历史记录、别名等。 <br><br>BASH 是一种解释执行的语言,我们还见过其他一些解释性的语言,如 BASIC 语言、Perl 语言、TCL/TL 等等。解释执行的语言的与编译型语言(如 C 语言)的最大不同就在于运行速度和使用方便程度上。BASH 和后面我们要讲解的 Perl 语言都是解释性语言,他们编写起来很方便,也很快捷,但是由于是解释执行,所以运行速度和效率必将大打折扣。故而今天介绍的 BASH 和 Perl 这两种解释性语言最好的用途就是一些用于完成特定功能的常用的小工具或小程序,对于一些大型的项目、计算复杂的工程或有高级需求的应用还是用 C 语言甚至汇编语言比较好。 <br><br>下面给出一些 BASH 所不适用的范围: <br><br>资源型敏感,对 CPU 负担重的程序 <br>复杂的大项目 <br>需要灵活处理文件的程序,BASH 只能逐行读出文件进行处理 <br>需要图形用户界面的程序<br>需要直接与系统硬件打交道的程序 <br>需要访问 I/O 端口和网络套接字的程序<br>需要使用库或和以前的其他代码整合的程序 <br><br>如果遇到上面这些程序,我们推荐最好用其他编程语言,如:Perl, Tcl, Python 或者直接用 C, C++, Java 。<br>                       
3#
 楼主| 发表于 28.11.2002 11:45:30 | 只看该作者
                          <br>2    BASH 的基本语法<br>最简单的例子 —— Hello World&#33; <br><br>关于输入、输出和错误输出 <br><br>BASH 中对变量的规定(与 C 语言的异同) <br><br>BASH 中的基本流程控制语法 <br><br>函数的使用 <br><br>2.1    最简单的例子 —— Hello World&#33;<br>几乎所有的讲解编程的书给读者的第一个例子都是 Hello World 程序,那么我们今天也就从这个例子出发,来逐步了解 BASH。<br><br>用 vi 编辑器编辑一个 hello 文件如下:<br><br>#&#33;/bin/bash <br># This is a very simple example<br>echo Hello World <br><br>这样最简单的一个 BASH 程序就编写完了。这里有几个问题需要说明一下:<br><br>一,第一行的 #&#33; 是什么意思<br>二,第一行的 /bin/bash 又是什么意思<br>三,第二行是注释吗 <br>四,echo 语句<br>五,如何执行该程序<br><br>#&#33; 是说明 hello 这个文件的类型的,有点类似于 Windows 系统下用不同文件后缀来表示不同文件类型的意思(但不相同)。Linux 系统根据 &quot;#&#33;&quot; 及该字串后面的信息确定该文件的类型,关于这一问题同学们回去以后可以通过 &quot;man magic&quot;命令 及 /usr/share/magic 文件来了解这方面的更多内容。在 BASH 中 第一行的 &quot;#&#33;&quot; 及后面的 &quot;/bin/bash&quot; 就表明该文件是一个 BASH 程序,需要由 /bin 目录下的 bash 程序来解释执行。BASH 这个程序一般是存放在 /bin 目录下,如果你的 Linux 系统比较特别,bash 也有可能被存放在 /sbin 、/usr/local/bin 、/usr/bin 、/usr/sbin 或 /usr/local/sbin 这样的目录下;如果还找不到,你可以用 &quot;locate bash&quot; &quot;find / -name bash 2&gt; /dev/null&quot; 或 &quot;whereis bash&quot; 这三个命令找出 bash 所在的位置;如果仍然找不到,那你可能需要自己动手安装一个 BASH 软件包了。<br><br>第二行的 &quot;# This is a ...&quot; 就是 BASH 程序的注释,在 BASH 程序中从“#”号(注意:后面紧接着是“&#33;”号的除外)开始到行尾的多有部分均被看作是程序的注释。的三行的 echo 语句的功能是把 echo 后面的字符串输出到标准输出中去。由于 echo 后跟的是 &quot;Hello World&quot; 这个字符串,因此 &quot;Hello World&quot;这个字串就被显示在控制台终端的屏幕上了。需要注意的是 BASH 中的绝大多数语句结尾处都没有分号。<br><br>如何执行该程序呢?有两种方法:一种是显式制定 BASH 去执行:<br><br>$ bash hello 或<br>$ sh hello (这里 sh 是指向 bash 的一个链接,“lrwxrwxrwx 1 root root 4 Aug 20 05:41 /bin/sh -&gt; bash”)<br><br>或者可以先将 hello 文件改为可以执行的文件,然后直接运行它,此时由于 hello 文件第一行的 &quot;#&#33; /bin/bash&quot; 的作用,系统会自动用/bin/bash 程序去解释执行 hello 文件的:<br><br>$ chmod u+x hello<br>$ ./hello<br><br>此处没有直接 “$ hello”是因为当前目录不是当前用户可执行文件的默认目录,而将当前目录“.”设为默认目录是一个不安全的设置。<br><br>需要注意的是,BASH 程序被执行后,实际上 Linux 系统是另外开设了一个进程来运行的。<br><br><br><br>2.2    关于输入、输出和错误输出<br>在字符终端环境中,标准输入/标准输出的概念很好理解。输入即指对一个应用程序或命令的输入,无论是从键盘输入还是从别的文件输入;输出即指应用程序或命令产生的一些信息;与 Windows 系统下不同的是,Linux 系统下还有一个标准错误输出的概念,这个概念主要是为程序调试和系统维护目的而设置的,错误输出于标准输出分开可以让一些高级的错误信息不干扰正常的输出信息,从而方便一般用户的使用。<br><br>在 Linux 系统中:标准输入(stdin)默认为键盘输入;标准输出(stdout)默认为屏幕输出;标准错误输出(stderr)默认也是输出到屏幕(上面的 std 表示 standard)。在 BASH 中使用这些概念时一般将标准输出表示为 1,将标准错误输出表示为 2。下面我们举例来说明如何使用他们,特别是标准输出和标准错误输出。<br><br>输入、输出及标准错误输出主要用于 I/O 的重定向,就是说需要改变他们的默认设置。先看这个例子:<br><br>$ ls &gt; ls_result<br>$ ls -l &gt;&gt; ls_result<br><br>上面这两个命令分别将 ls 命令的结果输出重定向到 ls_result 文件中和追加到 ls_result 文件中,而不是输出到屏幕上。&quot;&gt;&quot;就是输出(标准输出和标准错误输出)重定向的代表符号,连续两个 &quot;&gt;&quot; 符号,即 &quot;&gt;&gt;&quot; 则表示不清除原来的而追加输出。下面再来看一个稍微复杂的例子:<br><br>$ find /home -name lost* 2&gt; err_result<br><br>这个命令在 &quot;&gt;&quot; 符号之前多了一个 &quot;2&quot;,&quot;2&gt;&quot; 表示将标准错误输出重定向。由于 /home 目录下有些目录由于权限限制不能访问,因此会产生一些标准错误输出被存放在 err_result 文件中。大家可以设想一下 find /home -name lost* 2&gt;&gt;err_result 命令会产生什么结果?<br><br>如果直接执行 find /home -name lost* &gt; all_result ,其结果是只有标准输出被存入 all_result 文件中,要想让标准错误输出和标准输入一样都被存入到文件中,那该怎么办呢?看下面这个例子:<br><br>$ find /home -name lost* &gt; all_result 2&gt;&amp; 1<br><br>上面这个例子中将首先将标准错误输出也重定向到标准输出中,再将标准输出重定向到 all_result 这个文件中。这样我们就可以将所有的输出都存储到文件中了。为实现上述功能,还有一种简便的写法如下:<br><br>$ find /home -name lost* &gt;&amp; all_result<br><br>如果那些出错信息并不重要,下面这个命令可以让你避开众多无用出错信息的干扰:<br><br>$ find /home -name lost* 2&gt; /dev/null<br><br><br>同学们回去后还可以再试验一下如下几种重定向方式,看看会出什么结果,为什么?<br><br><br>$ find /home -name lost* &gt; all_result 1&gt;&amp; 2 <br>$ find /home -name lost* 2&gt; all_result 1&gt;&amp; 2<br>$ find /home -name lost* 2&gt;&amp; 1 &gt; all_result <br><br>另外一个非常有用的重定向操作符是 &quot;-&quot;,请看下面这个例子:<br><br>$ (cd /source/directory &amp;&amp; tar cf - . ) | (cd /dest/directory &amp;&amp; tar xvfp -) <br><br>该命令表示把 /source/directory 目录下的所有文件通过压缩和解压,快速的全部移动到 /dest/directory 目录下去,这个命令在 /source/directory 和 /dest/directory 不处在同一个文件系统下时将显示出特别的优势。<br><br>下面还几种不常见的用法:<br><br>n&lt;&amp;- 表示将 n 号输入关闭 <br>&lt;&amp;- 表示关闭标准输入(键盘)<br>n&gt;&amp;- 表示将 n 号输出关闭<br>&gt;&amp;- 表示将标准输出关闭<br><br> <br><br>2.3    BASH 中对变量的规定(与 C 语言的异同)<br>好了下面我们进入正题,先看看 BASH 中的变量是如何定义和使用的。对于熟悉 C 语言的程序员,我们将解释 BASH 中的定义和用法与 C 语言中有何不同。<br><br>2.3.1. BASH 中的变量介绍<br>我们先来从整体上把握一下 BASH 中变量的用法,然后再去分析 BASH 中变量使用与 C 语言中的不同。BASH 中的变量都是不能含有保留字,不能含有 &quot;-&quot; 等保留字符,也不能含有空格。<br><br>2.3.1.1 简单变量<br>在 BASH 中变量定义是不需要的,没有 &quot;int i&quot; 这样的定义过程。如果想用一个变量,只要他没有在前面被定义过,就直接可以用,当然你使用该变量的第一条语句应该是对他赋初值了,如果你不赋初值也没关系,只不过该变量是空( 注意:是 NULL,不是 0 )。不给变量赋初值虽然语法上不反对,但不是一个好的编程习惯。好了我们看看下面的例子:<br><br>首先用 vi 编辑下面这个文件 hello2:<br><br>#&#33;/bin/bash <br># give the initialize value to STR<br>STR=&quot;Hello World&quot; <br>echo $STR <br><br>在上面这个程序中我们需要注意下面几点:<br><br>一,变量赋值时,&#39;=&#39;左右两边都不能有空格;<br>二,BASH 中的语句结尾不需要分号(&quot;;&quot;);<br>三,除了在变量赋值和在FOR循环语句头中,BASH 中的变量使用必须在变量前加&quot;$&quot;符号,同学们可以将上面程序中第三行改为 &quot;echo STR&quot; 再试试,看看会出什么结果。<br>四,由于 BASH 程序是在一个新的进程中运行的,所以该程序中的变量定义和赋值不会改变其他进程或原始 Shell 中同名变量的值,也不会影响他们的运行。<br><br>更细致的文档甚至提到以但引号括起来的变量将不被 BASH 解释为变量,如 &#39;$STR&#39; ,而被看成为纯粹的字符串。而且更为标准的变量引用方式是 ${STR} 这样的,$STR 自不过是对 ${STR} 的一种简化。在复杂情况下(即有可能产生歧义的地方)最好用带 {} 的表示方式。<br><br>BASH 中的变量既然不需要定义,也就没有类型一说,一个变量即可以被定义为一个字符串,也可以被再定义为整数。如果对该变量进行整数运算,他就被解释为整数;如果对他进行字符串操作,他就被看作为一个字符串。请看下面的例子:<br><br>#&#33;/bin/bash <br>x=1999 <br>let &quot;x = $x + 1&quot; <br>echo $x <br>x=&quot;olympic&#39;&quot;$x <br>echo $x<br><br>关于整数变量计算,有如下几种:&quot; + - * / % &quot;,他们的意思和字面意思相同。整数运算一般通过 let 和 expr 这两个指令来实现,如对变量 x 加 1 可以写作:let &quot;x = $x + 1&quot; 或者 x=`expr $x + 1`<br><br>在比较操作上,整数变量和字符串变量各不相同,详见下表:<br><br>对应的操作 整数操作 字符串操作 <br>相同 -eq = <br>不同 -ne &#33;= <br>大于 -gt &gt; <br>小于 -lt &lt; <br>大于或等于 -ge  <br>小于或等于 -le  <br>为空  -z <br>不为空  -n <br><br><br>比如:<br><br>比较字符串 a 和 b 是否相等就写作:if [ $a = $b ]<br>判断字符串 a 是否为空就写作: if [ -z $a ]<br>判断整数变量 a 是否大于 b 就写作:if [ $a -gt $b ]<br><br>更细致的文档推荐在字符串比较时尽量不要使用 -n ,而用 &#33; -z 来代替。(其中符号 &quot;&#33;&quot; 表示求反操作)<br><br>BASH 中的变量除了用于对 整数 和 字符串 进行操作以外,另一个作用是作为文件变量。BASH 是 Linux 操作系统的 Shell,因此系统的文件必然是 BASH 需要操作的重要对象,如 if [ -x /root ] 可以用于判断 /root 目录是否可以被当前用户进入。下表列出了 BASH 中用于判断文件属性的操作符:<br><br>运算符 含义( 满足下面要求时返回 TRUE ) <br>-e file 文件 file 已经存在 <br>-f file 文件 file 是普通文件 <br>-s file 文件 file 大小不为零 <br>-d file 文件 file 是一个目录 <br>-r file 文件 file 对当前用户可以读取 <br>-w file 文件 file 对当前用户可以写入 <br>-x file 文件 file 对当前用户可以执行 <br>-g file 文件 file 的 GID 标志被设置 <br>-u file 文件 file 的 UID 标志被设置 <br>-O file 文件 file 是属于当前用户的 <br>-G file 文件 file 的组 ID 和当前用户相同 <br>file1 -nt file2 文件 file1 比 file2 更新 <br>file1 -ot file2 文件 file1 比 file2 更老 <br><br><br>注意:上表中的 file 及 file1、file2 都是指某个文件或目录的路径。<br><br>2.3.1.1. 关于局部变量<br>在 BASH 程序中如果一个变量被使用了,那么直到该程序的结尾,该变量都一直有效。为了使得某个变量存在于一个局部程序块中,就引入了局部变量的概念。BASH 中,在变量首次被赋初值时加上 local 关键字就可以声明一个局部变量,如下面这个例子:<br><br>#&#33;/bin/bash <br>HELLO=Hello <br>function hello { <br>  local HELLO=World <br>  echo $HELLO <br>} <br>echo $HELLO <br>hello <br>echo $HELLO<br><br>该程序的执行结果是:<br><br>Hello<br>World<br>Hello <br><br>这个执行结果表明全局变量 $HELLO 的值在执行函数 hello 时并没有被改变。也就是说局部变量 $HELLO 的影响只存在于函数那个程序块中。<br><br>2.3.2. BASH 中的变量与 C 语言中变量的区别<br>这里我们为原来不熟悉 BASH 编程,但是非常熟悉 C 语言的程序员总结一下在 BASH 环境中使用变量需要注意的问题。<br><br>1,BASH 中的变量在引用时都需要在变量前加上 &quot;$&quot; 符号( 第一次赋值及在For循环的头部不用加 &quot;$&quot;符号 );<br>2,BASH 中没有浮点运算,因此也就没有浮点类型的变量可用;<br>3,BASH 中的整形变量的比较符号与 C 语言中完全不同,而且整形变量的算术运算也需要经过 let 或 expr 语句来处理;<br><br>2.4    BASH 中的基本流程控制语法<br>BASH 中几乎含有 C 语言中常用的所有控制结构,如条件分支、循环等,下面逐一介绍。 <br><br>2.4.1 if...then...else<br>if 语句用于判断和分支,其语法规则和 C 语言的 if 非常相似。其几种基本结构为: <br><br>if [ expression ]<br>then<br>  statments<br>fi <br><br>或者 <br><br>if [ expression ]<br>then<br>  statments<br>else<br>  statments<br>fi <br><br>或者 <br><br>if [ expression ]<br>then<br>  statments<br>else if [ expression ]<br>  then <br>    statments<br>  else<br>    statments <br>fi <br><br>或者 <br><br>if [ expression ]<br>then<br>  statments<br>elif [ expression ]<br>  then<br>    statments<br>  else<br>    statments<br>fi <br><br>值得说明的是如果你将 if 和 then 简洁的写在一行里面,就必须在 then 前面加上分号,如:if [ expression ]; then ... 。下面这个例子说明了如何使用 if 条件判断语句: <br><br>#&#33;/bin/bash <br><br>if [ $1 -gt 90 ] <br>then <br>  echo &quot;Good, $1&quot; <br>elif [ $1 -gt 70 ] <br>  then <br>    echo &quot;OK, $1&quot; <br>  else <br>    echo &quot;Bad, $1&quot; <br>fi <br><br>exit 0 <br><br>上面例子中的 $1 是指命令行的第一个参数,这个会在后面的“BASH 中的特殊保留字”中讲解。 <br><br>2.4.2 for<br>for 循环结构与 C 语言中有所不同,在 BASH 中 for 循环的基本结构是: <br><br>for $var in <ul><br>do<br>  statments<br>done <br><br>其中 $var 是循环控制变量,<ul> 是 $var 需要遍历的一个集合,do/done 对包含了循环体,相当于 C 语言中的一对大括号。另外如果do 和 for 被写在同一行,必须在 do 前面加上 &quot;;&quot;。如: for $var in <ul>; do 。下面是一个运用 for 进行循环的例子:<br><br>#&#33;/bin/bash <br><br>for day in Sun Mon Tue Wed Thu Fri Sat <br>do <br>  echo $day <br>done <br><br># 如果列表被包含在一对双引号中,则被认为是一个元素 <br>for day in &quot;Sun Mon Tue Wed Thu Fri Sat&quot; <br>do <br>  echo $day <br>done <br><br>exit 0<br><br>注意上面的例子中,在 for 所在那行的变量 day 是没有加 &quot;$&quot; 符号的,而在循环体内,echo 所在行变量 $day 是必须加上 &quot;$&quot; 符号的。另外如果写成 for day 而没有后面的 in <ul> 部分,则 day 将取遍命令行的所有参数。如这个程序:<br><br>#&#33;/bin/bash <br><br>for param <br>do <br>  echo $param <br>done <br><br>exit 0<br><br>上面这个程序将列出所有命令行参数。for 循环结构的循环体被包含在 do/done 对中,这也是后面的 while、until 循环所具有的特点。<br><br>2.4.3 while<br>while 循环的基本结构是: <br><br>while [ condition ]<br>do<br>  statments<br>done <br><br>这个结构请大家自己编写一个例子来验证。 <br><br>2.4.4 until<br>until 循环的基本结构是: <br><br>until [ condition is TRUE ]<br>do<br>  statments<br>done <br><br>这个结构也请大家自己编写一个例子来验证。 <br><br>2.4.5 case<br>BASH 中的 case 结构与 C 语言中的 switch 语句的功能比较类似,可以用于进行多项分支控制。其基本结构是: <br><br>case &quot;$var&quot; in<br> condition1 )<br>  statments1;;<br> condition2 )<br>  statments2;;<br> ...<br> * )<br>  default statments;;<br>esac <br><br>下面这个程序是运用 case 结构进行分支执行的例子: <br><br>#&#33;/bin/bash <br><br>echo &quot;Hit a key, then hit return.&quot; <br>read Keypress <br><br>case &quot;$Keypress&quot; in <br> [a-z] ) echo &quot;Lowercase letter&quot;;; <br> [A-Z] ) echo &quot;Uppercase letter&quot;;; <br> [0-9] ) echo &quot;Digit&quot;;; <br> * ) echo &quotunctuation, whitespace, or other&quot;;; <br>esac <br><br>exit 0 <br><br>上面例子中的第四行 &quot;read Keypress&quot; 一句中的 read 语句表示从键盘上读取输入。这个命令将在本讲义的 BASH 的其他高级问题中讲解。 <br><br>2.4.6 break/continue<br>熟悉 C 语言编程的都很熟悉 break 语句和 continue 语句。BASH 中同样有这两条语句,而且作用和用法也和 C 语言中相同,break 语句可以让程序流程从当前循环体中完全跳出,而 continue 语句可以跳过当次循环的剩余部分并直接进入下一次循环。 <br><br>  <br><br>2.5    函数的使用<br>BASH 是一个相对简单的脚本语言,不过为了方便结构化的设计,BASH 中也提供了函数定义的功能。BASH 中的函数定义很简单,只要向下面这样写就可以了: <br><br>function my_funcname { <br> code block<br>} <br><br>或者 <br><br>my_funcname() { <br> code block<br>} <br><br>上面的第二种写法更接近于 C 语言中的写法。BASH 中要求函数的定义必须在函数使用之前,这是和 C 语言用头文件说明函数方法的不同。 <br><br>更进一步的问题是如何给函数传递参数和获得返回值。BASH 中函数参数的定义并不需要在函数定义处就制定,而只需要在函数被调用时用 BASH 的保留变量 $1 $2 ... 来引用就可以了;BASH 的返回值可以用 return 语句来指定返回一个特定的整数,如果没有 return 语句显式的返回一个返回值,则返回值就是该函数最后一条语句执行的结果(一般为 0,如果执行失败返回错误码)。函数的返回值在调用该函数的程序体中通过 $? 保留字来获得。下面我们就来看一个用函数来计算整数平方的例子: <br><br>#&#33;/bin/bash <br><br>square() { <br> let &quot;res = $1 * $1&quot; <br> return $res <br>} <br><br>square $1 <br>result=$? <br>echo $result <br><br>exit 0 <br>                       
4#
 楼主| 发表于 28.11.2002 11:46:37 | 只看该作者
                          <br>3    BASH 中的特殊保留字<br>保留变量 <br><br>随机数 <br><br>运算符 <br><br>变量的特殊操作 <br><br>3.1    保留变量<br>BASH 中有一些保留变量,下面列出了一些:<br><br>$IFS  这个变量中保存了用于分割输入参数的分割字符,默认识空格。 <br>$HOME  这个变量中存储了当前用户的根目录路径。 <br>$ATH  这个变量中存储了当前 Shell 的默认路径字符串。 <br>$S1  表示第一个系统提示符。 <br>$S2  表示的二个系统提示符。 <br>$WD  表示当前工作路径。 <br>$EDITOR 表示系统的默认编辑器名称。 <br>$BASH  表示当前 Shell 的路径字符串。<br>$0, $1, $2, ... <br>    表示系统传给脚本程序或脚本程序传给函数的第0个、第一个、第二个等参数。<br>$#   表示脚本程序的命令参数个数或函数的参数个数。<br>$$   表示该脚本程序的进程号,常用于生成文件名唯一的临时文件。 <br>$?   表示脚本程序或函数的返回状态值,正常为 0,否则为非零的错误号。<br>$*   表示所有的脚本参数或函数参数。<br>$@   和 $* 涵义相似,但是比 $* 更安全。<br>$&#33;   表示最近一个在后台运行的进程的进程号。<br><br><br><br>3.2    随机数<br>随机数是经常要用到的,BASH 中也提供了这个功能,请看下面这个程序:<br><br>#&#33;/bin/bash <br><br># Prints different random integer from 1 to 65536 <br><br>a=$RANDOM <br>echo $a <br><br>exit 0 <br><br>这个程序可以在每次执行的时候随机的打印出一个大小在 1 到 65536 之间的整数。<br><br> <br><br>3.3    运算符<br>算术运算符 <br>+ - * / % 表示加减乘除和取余运算<br>+= -= *= /= 同 C 语言中的含义<br><br>位操作符<br>&lt;&lt; &lt;&lt;= &gt;&gt; &gt;&gt;= 表示位左右移一位操作<br>&amp; &amp;= | |= 表示按位与、位或操作<br>~ &#33; 表示非操作<br>^ ^= 表示异或操作 <br><br>关系运算符 <br>&lt; &gt; &lt;= &gt;= == &#33;= 表示大于、小于、大于等于、小于等于、等于、不等于操作<br>&amp;&amp; || 逻辑与、逻辑或操作<br><br><br>  <br><br><br>3.4    变量的特殊操作<br>BASH 中还有一些对变量的简洁、快速的操作,大家还记得 &quot;${var}&quot; 和 &quot;$var&quot; 同样是对变量的引用吧,对 ${var} 进行一些变化就可以产生一些新功能:<br>${var-default} 表示如果变量 $var 还没有设置,则保持 $var 没有设置的状态,并返回后面的默认值 default。<br>${var=default} 表示如果变量 $var 还没有设置,则取后面的默认值 default。 <br>${var+otherwise} 表示如果变量 $var 已经设置,则返回 otherwise 的值,否则返回空( null )。<br>${var?err_msg} 表示如果变量 $var 已经设置,则返回该变量的值,否则将后面的 err_msg 输出到标准错误输出上。 <br><br>请同学们自己尝试下面的例子:<br><br>#&#33;/bin/bash<br><br>echo ${var?There is an error}<br><br>exit 0<br><br>还有下面一些用法,这些用法主要用于从文件路径字符串中提取有用信息:<br>${var#pattern}, ${var##pattern} 用于从变量 $var 中剥去最短(最长)的和 pattern 相匹配的最左侧的串。<br>${var%pattern}, ${var%%pattern} 用于从变量 $var 中剥去最短(最长)的和 pattern 相匹配的最右侧的串。<br><br>另外 BASH 2 中还加入下面一些操作:<br>${var:pos} 表示去掉变量 $var 中前 pos 个字符。<br>${var:pos:len} 表示变量 $var 中去掉前 pos 个字符后的剩余字符串的前 len 个字符。<br>${var/pattern/replacement} 表示将变量 $var 中第一个出现的 pattern 模式替换为 replacement 字符串。<br>${var//pattern/replacement} 表示将变量 $var 中出现的所有 pattern 模式全部都替换为 replacment 字符串。<br><br><br>                          
5#
 楼主| 发表于 28.11.2002 11:47:18 | 只看该作者
                          <br>4    BASH 中的其他高级问题<br>BASH 中对返回值的处理 <br><br>用 BASH 设计简单用户界面 <br><br>在 BASH 中读取用户输入 <br><br>一些特殊的惯用法 <br><br>BASH 程序的调试 <br><br>关于 BASH2 <br><br>4.1    BASH 中对返回值的处理<br>无论是在 Shell 中对 BASH 脚本返回值的处理,还是在脚本中对函数返回值的处理,都是通过 &quot;$?&quot; 系统变量来获得。BASH 要求返回值必须为一个整数,不能用 return 语句返回字符串变量。<br><br><br><br>4.2    用 BASH 设计简单用户界面<br>BASH 中提供了一个小的语句格式,可以让程序快速的设计出一个字符界面的用户交互选择的菜单,该功能就是由 select 语句来实现的,select 语句的语法为:<br><br>select var in <ul><br>do<br> statments use $var<br>done<br><br>上面的语法结构在执行后,BASH 会将 <ul> 中的所有项加上数字列在屏幕上等待用户选择,在用户作出选择后,变量 $var 中就包含了那个被选中的字符串,然后就可以对该变量进行需要的操作了。我们可以从下面的例子中更直观的来理解这个功能: <br><br>#&#33;/bin/bash <br><br>OPTIONS=&quot;Hello Quit&quot; <br>select opt in $OPTIONS; do <br> if [ &quot;$opt&quot; = &quot;Quit&quot; ]; then <br>  echo done <br>  exit <br> elif [ &quot;$opt&quot; = &quot;Hello&quot; ]; then <br>   echo Hello World <br>  else <br>   clear <br>   echo bad option <br> fi <br>done <br><br>exit 0<br><br>大家可以试着执行上面的程序,看看是什么执行结果。<br><br> <br><br><br>4.3    在 BASH 中读取用户输入<br>BASH 中通过 read 函数来实现读取用户输入的功能,如下面这段程序:<br><br>#&#33;/bin/bash<br><br>echo Please enter your name<br>read NAME <br>echo &quot;Hi&#33; $NAME &#33;&quot;<br><br>exit 0<br><br>上面这个脚本读取用户的输入,并回显在屏幕上。<br><br>另外 BASH 中还提供另外一种称为 here documents 的结构,可以将用户需要通过键盘输入的字符串改为从程序体中直接读入,如密码。下面的小程序演示了这个功能:<br><br>#&#33;/bin/bash <br><br>passwd=&quot;aka@tsinghua&quot; <br>ftp -n localhost &lt;&lt;FTPFTP<br>user anonymous $passwd <br>binary <br>bye <br>FTPFTP <br><br>exit 0 <br><br>这个程序在用户需要通过键盘敲入一些字符时,通过程序内部的动作来模拟键盘输入。请注意 here documents 的基本结构为:<br><br>command &lt;&lt;SOMESPECIALSTRING<br>statments<br>...<br>SOMESPECIALSTRING<br><br>这里要求在需要键盘输入的命令后,直接加上 &lt;&lt;符号,然后跟上一个特别的字符串,在该串后按顺序输入本来应该由键盘输入的所有字符,在所有需要输入的字符都结束后,重复一遍前面 &lt;&lt;符号后的“特别的字符串”即表示该输入到此结束。<br><br> <br><br>4.4 一些特殊的惯用法<br>在 BASH 中 () 一对括号一般被用于求取括号中表达式的值或命令的执行结果,如:(a=hello; echo $a) ,其作用相当于 `...` 。 <br><br>: 有两个含义,一是表示空语句,有点类似于 C 语言中的单个 &quot;;&quot; 。表示该行是一个空命令,如果被用在 while/until 的头结构中,则表示值 0,会使循环一直进行下去,如下例:<br><br>while : <br>do <br> operation-1 <br> operation-2 <br> ... <br> operation-n <br>done <br><br>另外 : 还可以用于求取后面变量的值,比如:<br><br>#&#33;/bin/bash <br><br>: ${HOSTNAME?} {USER?} {MAIL?} <br>echo $HOSTNAME <br>echo $USER <br>echo $MAIL <br><br>exit 0 <br><br>在 BASH 中 export 命令用于将系统变量输出到外层的 Shell 中了。<br><br> <br><br>4.5 BASH 程序的调试<br>用 bash -x bash-script 命令,可以查看一个出错的 BASH 脚本到底错在什么地方,可以帮助程序员找出脚本中的错误。<br><br>另外用 trap 语句可以在 BASH 脚本出错退出时打印出一些变量的值,以供程序员检查。trap 语句必须作为继 &quot;#&#33;/bin/bash&quot; 后的第一句非注释代码,一般 trap 命令被写作: trap &#39;message $checkvar1 $checkvar2&#39; EXIT 。<br><br> <br><br>4.6 关于 BASH2<br>使用 bash -version 命令可以看出当前你正在使用的 BASH 是什么版本,一般版本号为1.14或其他版本。而现在机器上一般还安装了一个版本号为 2.0 的 BASH 。该 BASH 也在 /bin 目录下。BASH2 提供了一些新功能,有兴趣的同叙可以自己去看相关资料,或直接 man bash2 即可。<br>                          
6#
 楼主| 发表于 28.11.2002 11:47:47 | 只看该作者
                          <br>5    Perl 的特点、历史和许可证<br>erl 的基本特点 <br><br>erl 的发展历史 <br><br>erl 的使用许可证 <br><br>5.1    Perl 的基本特点<br>  别期望在一刻钟内就能领略Perl的所有神奇之处, 这种情况很像吃香蕉, 用不着吃完整只香蕉后才知其味,每咬一口都是享受,并促使你再咬下一口,再下一口。                       ----Larry Wall <br><br>上面这段话是 Perl 项目发起人劳利·华尔( Larry Wall )对学习 Perl 语言的一段经典评论,希望大家都能找到这种感觉。<br><br>  Perl 是 Practical Extraction and Report Language (实用摘录和报告语言)的简称,是由 Larry Wall 所发起的。现在其最新版本为5.0,但是大家急切期待是 Perl 6.0 的诞生,不过本次讲座中我们还是以 5.0 为基础。<br><br>  Perl 的设计目标是帮助 UNIX 用户完成一些常见的任务,这些任务对于 Shell 来说过于沉重或对移植性要求过于严格。Perl 语言中包含了 C、C++、shell,script、sed、awk 这几个语言的语法,它最初的目的就是用来取代 UNIX 中 sed/awk 与 脚本语言的组合,用来汇整信息,产生报表。因此 Perl 语言要远远比前面讲的 BASH 复杂和功能强大。<br><br>  Perl 的设计原则或者说 Perl 的设计哲学是以实用为第一优先,也就是力图使 Perl 语言容易使用、有效率、而且完整。<br><br>  Perl 是按 GNU Public License 和 Artictic License 两种许可证形式分发的,其实质是开源软件、自由软件的,原先运行于 UNIX 和类 UNIX 系统,现在已可以方便地在OS/2,Windows 9x,Windows/NT等系统下运行。<br><br>  Perl 是一种解释运行的语言,和 BASH 程序一样,一般 Perl 程序的第一行需注明自己是一个 Perl 程序而不是 Shell 程序,所以一般将下面一行语句:<br>  #&#33; /usr/bin/perl   作为文件的第一行。 <br><br>  Perl 由于引入了模块的设计思想,随着版本的改进,功能越来越强。现在 Perl 的功能已经超乎原先设计时的想象,几乎任何事都可以做到,也变成每一部工作站必备的标准工具了。Perl 最为著名的一点就是他对字符串的处理,由于 Internet 对文字信息处理的巨大需求,使得 Perl 的应用如日中天,而且 Perl 语言也的确是一个非常优秀的文字信息处理语言。<br><br><br><br><br>5.2    Perl 的发展历史<br>最早发布的 Perl 1.0 版是在1987年底出现的,现在已经过去十多年了。下面是 Perl 首席开发者 Larry Wall 对 Perl 发展历程的一个简单回顾:<br><br>    Perl 0 introduced Perl to my officemates.<br>    Perl 1 introduced Perl to the world, and changed /\(...\|...\)/ to<br>        /(...|...)/.  \(Dan Faigin still hasn&#39;t forgiven me. :-\)<br>    Perl 2 introduced Henry Spencer&#39;s regular expression package.<br>    Perl 3 introduced the ability to handle binary data (embedded nulls).<br>    Perl 4 introduced the first Camel book.  Really.  We mostly just<br>        switched version numbers so the book could refer to 4.000.<br>    Perl 5 introduced everything else, including the ability to<br>        introduce everything else.<br>erl 从诞生到现在(Year 2000),他的主要开发参与者有 10 位,他们分别是:<br>  Larry Wall, <br>  Andy Dougherty, <br>  Tom Christiansen, <br>  Charles Bailey, <br>  Nick Ing-Simmons, <br>  Chip Salzenberg, <br>  Tim Bunce, <br>  Malcolm Beattie, <br>  Gurusamy Sarathy, <br>  Graham Barr. <br><br>下面是一个关于 Perl 历史上各种发行版本的汇总表:<br><br> 开发者  版本号         发布日期        备注 <br> ===========================================================================<br><br> Larry   0              Classified.     Don&#39;t ask.<br><br> Larry   1.000          1987-Dec-18<br><br>          1.001..10     1988-Jan-30<br>          1.011..14     1988-Feb-02<br><br> Larry   2.000          1988-Jun-05<br><br>          2.001         1988-Jun-28<br><br> Larry   3.000          1989-Oct-18<br><br>          3.001         1989-Oct-26<br>          3.002..4      1989-Nov-11<br>          3.005         1989-Nov-18<br>          3.006..8      1989-Dec-22<br>          3.009..13     1990-Mar-02<br>          3.014         1990-Mar-13<br>          3.015         1990-Mar-14<br>          3.016..18     1990-Mar-28<br>          3.019..27     1990-Aug-10     User subs.<br>          3.028         1990-Aug-14<br>          3.029..36     1990-Oct-17<br>          3.037         1990-Oct-20<br>          3.040         1990-Nov-10<br>          3.041         1990-Nov-13<br>          3.042..43     1990-Jan-??<br>          3.044         1991-Jan-12<br><br> Larry   4.000          1991-Mar-21<br><br>          4.001..3      1991-Apr-12<br>          4.004..9      1991-Jun-07<br>          4.010         1991-Jun-10<br>          4.011..18     1991-Nov-05<br>          4.019         1991-Nov-11     Stable.<br>          4.020..33     1992-Jun-08<br>          4.034         1992-Jun-11<br>          4.035         1992-Jun-23<br> Larry    4.036         1993-Feb-05     Very stable.<br><br>          5.000alpha1   1993-Jul-31<br>          5.000alpha2   1993-Aug-16<br>          5.000alpha3   1993-Oct-10<br>          5.000alpha4   1993-???-??<br>          5.000alpha5   1993-???-??<br>          5.000alpha6   1994-Mar-18<br>          5.003alpha7   1994-Mar-25<br> Andy     5.000alpha8   1994-Apr-04<br> Larry    5.000alpha9   1994-May-05     ext appears.<br>          5.000alpha10  1994-???-??<br>          5.000alpha11  1994-???-??<br> Andy     5.000a11a     1994-Jul-07     To fit 14.<br>          5.000a11b     1994-Jul-14<br>          5.000a11c     1994-Jul-19<br>          5.000a11d     1994-Jul-22<br> Larry    5.000alpha12  1994-???-??<br> Andy     5.000a12a     1994-Aug-08<br>          5.000a12b     1994-Aug-15<br>          5.000a12c     1994-Aug-22<br>          5.000a12d     1994-Aug-22<br>          5.000a12e     1994-Aug-22<br>          5.000a12f     1994-Aug-24<br>          5.000a12g     1994-Aug-24<br>          5.000a12h     1994-Aug-24<br> Larry    5.000beta1    1994-???-??<br> Andy     5.000b1a      1994-???-??<br> Larry    5.000beta2    1994-Sep-14     Core slushified.<br> Andy     5.000b2a      1994-Sep-14<br>          5.000b2b      1994-Sep-17<br>          5.000b2c      1994-Sep-17<br> Larry    5.000beta3    1994-Sep-??<br> Andy     5.000b3a      1994-Sep-18<br>          5.000b3b      1994-Sep-22<br>          5.000b3c      1994-Sep-23<br>          5.000b3d      1994-Sep-27<br>          5.000b3e      1994-Sep-28<br>          5.000b3f      1994-Sep-30<br>          5.000b3g      1994-Oct-04<br> Andy     5.000b3h      1994-Oct-07<br><br> Larry   5.000          1994-Oct-18<br><br> Andy     5.000a        1994-Dec-19<br>          5.000b        1995-Jan-18<br>          5.000c        1995-Jan-18<br>          5.000d        1995-Jan-18<br>          5.000e        1995-Jan-18<br>          5.000f        1995-Jan-18<br>          5.000g        1995-Jan-18<br>          5.000h        1995-Jan-18<br>          5.000i        1995-Jan-26<br>          5.000j        1995-Feb-07<br>          5.000k        1995-Feb-11<br>          5.000l        1995-Feb-21<br>          5.000m        1995-???-??<br>          5.000n        1995-Mar-07<br><br> Larry   5.001          1995-Mar-13<br><br> Andy     5.001a        1995-Mar-15<br>          5.001b        1995-Mar-31<br>          5.001c        1995-Apr-07<br>          5.001d        1995-Apr-14<br>          5.001e        1995-Apr-18     Stable.<br>          5.001f        1995-May-31<br>          5.001g        1995-May-25<br>          5.001h        1995-May-25<br>          5.001i        1995-May-30<br>          5.001j        1995-Jun-05<br>          5.001k        1995-Jun-06<br>          5.001l        1995-Jun-06     Stable.<br>          5.001m        1995-Jul-02     Very stable.<br>          5.001n        1995-Oct-31     Very unstable.<br>          5.002beta1    1995-Nov-21<br>          5.002b1a      1995-Nov-??<br>          5.002b1b      1995-Dec-04<br>          5.002b1c      1995-Dec-04<br>          5.002b1d      1995-Dec-04<br>          5.002b1e      1995-Dec-08<br>          5.002b1f      1995-Dec-08<br> Tom      5.002b1g      1995-Dec-21     Doc release.<br> Andy     5.002b1h      1996-Jan-05<br>          5.002b2       1996-Jan-14<br> Larry    5.002b3       1996-Feb-02<br> Andy     5.002gamma    1996-Feb-11<br> Larry    5.002delta    1996-Feb-27<br><br> Larry   5.002          1996-Feb-29     Prototypes.<br><br> Charles  5.002_01      1996-Mar-25<br><br>         5.003          1996-Jun-25     Security release.<br><br>          5.003_01      1996-Jul-31<br> Nick     5.003_02      1996-Aug-10<br> Andy     5.003_03      1996-Aug-28<br>          5.003_04      1996-Sep-02<br>          5.003_05      1996-Sep-12<br>          5.003_06      1996-Oct-07<br>          5.003_07      1996-Oct-10<br> Chip     5.003_08      1996-Nov-19<br>          5.003_09      1996-Nov-26<br>          5.003_10      1996-Nov-29<br>          5.003_11      1996-Dec-06<br>          5.003_12      1996-Dec-19<br>          5.003_13      1996-Dec-20<br>          5.003_14      1996-Dec-23<br>          5.003_15      1996-Dec-23<br>          5.003_16      1996-Dec-24<br>          5.003_17      1996-Dec-27<br>          5.003_18      1996-Dec-31<br>          5.003_19      1997-Jan-04<br>          5.003_20      1997-Jan-07<br>          5.003_21      1997-Jan-15<br>          5.003_22      1997-Jan-16<br>          5.003_23      1997-Jan-25<br>          5.003_24      1997-Jan-29<br>          5.003_25      1997-Feb-04<br>          5.003_26      1997-Feb-10<br>          5.003_27      1997-Feb-18<br>          5.003_28      1997-Feb-21<br>          5.003_90      1997-Feb-25     Ramping up to the 5.004 release.<br>          5.003_91      1997-Mar-01<br>          5.003_92      1997-Mar-06<br>          5.003_93      1997-Mar-10<br>          5.003_94      1997-Mar-22<br>          5.003_95      1997-Mar-25<br>          5.003_96      1997-Apr-01<br>          5.003_97      1997-Apr-03     Fairly widely used.<br>          5.003_97a     1997-Apr-05<br>          5.003_97b     1997-Apr-08<br>          5.003_97c     1997-Apr-10<br>          5.003_97d     1997-Apr-13<br>          5.003_97e     1997-Apr-15<br>          5.003_97f     1997-Apr-17<br>          5.003_97g     1997-Apr-18<br>          5.003_97h     1997-Apr-24<br>          5.003_97i     1997-Apr-25<br>          5.003_97j     1997-Apr-28<br>          5.003_98      1997-Apr-30<br>          5.003_99      1997-May-01<br>          5.003_99a     1997-May-09<br>          p54rc1        1997-May-12     Release Candidates.<br>          p54rc2        1997-May-14<br><br> Chip    5.004          1997-May-15     A major maintenance release.<br><br> Tim      5.004_01      1997-Jun-13     The 5.004 maintenance track.<br>          5.004_02      1997-Aug-07<br>          5.004_03      1997-Sep-05<br>          5.004_04      1997-Oct-15<br>          5.004m5t1     1998-Mar-04     Maintenance Trials (for 5.004_05).<br>          5.004_04-m2   1997-May-01<br>          5.004_04-m3   1998-May-15<br>          5.004_04-m4   1998-May-19<br>          5.004_04-MT5  1998-Jul-21<br><br> Malcolm  5.004_50      1997-Sep-09     The 5.005 development track.<br>          5.004_51      1997-Oct-02<br>          5.004_52      1997-Oct-15<br>          5.004_53      1997-Oct-16<br>          5.004_54      1997-Nov-14<br>          5.004_55      1997-Nov-25<br>          5.004_56      1997-Dec-18<br>          5.004_57      1998-Feb-03<br>          5.004_58      1998-Feb-06<br>          5.004_59      1998-Feb-13<br>          5.004_60      1998-Feb-20<br>          5.004_61      1998-Feb-27<br>          5.004_62      1998-Mar-06<br>          5.004_63      1998-Mar-17<br>          5.004_64      1998-Apr-03<br>          5.004_65      1998-May-15<br>          5.004_66      1998-May-29<br> Sarathy  5.004_67      1998-Jun-15<br>          5.004_68      1998-Jun-23<br>          5.004_69      1998-Jun-29<br>          5.004_70      1998-Jul-06<br>          5.004_71      1998-Jul-09<br>          5.004_72      1998-Jul-12<br>          5.004_73      1998-Jul-13<br>          5.004_74      1998-Jul-14     5.005 beta candidate.<br>          5.004_75      1998-Jul-15     5.005 beta1.<br>          5.004_76      1998-Jul-21     5.005 beta2.<br>          5.005         1998-Jul-22     Oneperl.<br><br> Sarathy  5.005_01      1998-Jul-27     The 5.005 maintenance track.<br>          5.005_02-T1   1998-Aug-02<br>          5.005_02-T2   1998-Aug-05<br>          5.005_02      1998-Aug-08<br> Graham   5.005_03      1998-           <br><br> Sarathy  5.005_50      1998-Jul-26     The 5.006 development track.<br><br>关于 Perl 发展历史的更详细信息大家可以从这里得到。<br><br><br><br>5.3    Perl 的使用许可证<br>我们应该知道 Perl 是一个开放源码的优秀软件,你可以自由的下载该软件去使用和研究,但是 Perl 使用的并不是我们熟知的 GPL 许可证,而是 Artistic 许可证,虽然 Artistic 许可证和 GPL 很类似。简单的说就是 Artistic 许可证比 GPL 的要宽松,你可以出售包含Artistic“包” 的产品,但是绝对不能出售Artistic“包”,不像GPL那么死板。 Artistic 许可证之所以不涉及源码问题是因为 Perl 不存在这个问题。可能大部分人都还不太了解这个许可证。下面是 Artistic 许可证的英文原文,有兴趣的同学可以自己看一遍。<br><br> <br><br><br>--------------------------------------------------------------------------------<br><br>The &quot;Artistic License&quot;<br>reamble<br>The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. <br><br>Definitions<br>&quot;Package&quot; refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. <br><br>&quot;Standard Version&quot; refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder as specified below. <br><br>&quot;Copyright Holder&quot; is whoever is named in the copyright or copyrights for the package. <br><br>&quot;You&quot; is you, if you&#39;re thinking about copying or distributing this Package. <br><br>&quot;Reasonable copying fee&quot; is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) <br><br>&quot;Freely Available&quot; means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. <br><br><br>You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. <br><br><br>You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. <br><br><br>You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: <br><br><br>place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as uunet.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. <br>use the modified Package only within your corporation or organization. <br>rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. <br>make other distribution arrangements with the Copyright Holder. <br><br><br>You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: <br><br><br>distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. <br>accompany the distribution with the machine-readable source of the Package with your modifications. <br>give non-standard executables non-standard names, and clearly document the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. <br>make other distribution arrangements with the Copyright Holder. <br><br><br>You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. You may embed this Package&#39;s interpreter within an executable of yours (by linking); this shall be construed as a mere form of aggregation, provided that the complete Standard Version of the interpreter is so embedded. <br><br><br>The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. If such scripts or library files are aggregated with this Package via the so-called &quot;undump&quot; or &quot;unexec&quot; methods of producing a binary executable image, then distribution of such an image shall neither be construed as a distribution of this Package nor shall it fall under the restrictions of Paragraphs 3 and 4, provided that you do not represent such an executable image as a Standard Version of this Package. <br><br><br>C subroutines (or comparably compiled subroutines in other languages) supplied by you and linked into this Package in order to emulate subroutines and variables of the language defined by this Package shall not be considered part of this Package, but are the equivalent of input as in Paragraph 6, provided these subroutines do not change the language in any way that would cause it to fail the regression tests for the language. <br><br><br>Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package&#39;s interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package. <br><br><br>The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. <br><br><br>THIS PACKAGE IS PROVIDED &quot;AS IS&quot; AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. <br><br>The End <br><br>--------------------------------------------------------------------------------<br><br>                          
7#
 楼主| 发表于 28.11.2002 11:48:09 | 只看该作者
                          <br>6    用 Perl 写 CGI 程序<br>为什么要用 Perl 来写 CGI <br><br>几个简单的 Perl CGI 程序 <br><br>CGI 中常用的环境变量 <br><br>关于 CGI 的更多内容 <br><br>6.1    为什么要用 Perl 来写 CGI<br>为什么要用Perl来写CGI 应用程序呢?<br><br>因为 Perl 有很强的字符串处理能力,尤其是利用关联性数组来作 CGI 应用程序剖析输入数据串,可以说是一个功能强大的语言。由于 Internet 上有大量的字符数据需要处理,因而在国外很多处理数据库的软件可以用 Perl 来沟通。现在 Perl 5.0 版本中增加了如下特色:<br>  面向对象的用法、<br>  增加对字符串的处理能力、<br>  可以把整个文件当成一个字符串来处理、<br>  不受任何数据的大小限制而只受存储器的大小限制、<br>  能够处理 DBM 数据库格式的数据,也能够处理二进制的数据 等等,<br>更重要的是 Perl 还可以在 UNIX、WindowsNT、Windows95、Dos、Linux、FreeBSD、OS2、Macitosh 等众多操作系统中使用。<br><br>另外 Perl 很容易学习和入门,虽然要精通需要一定的时间。它的语法和 C 语言很接近,对于原本熟悉 C 语言的人来说,Perl 是很容易上手的。只要几个小时的学习就可以很轻易地用 Perl 语言写一个简单的 CGI 应用程序;至于那些没有 C 语言基础的人,也只要多花一点时间来熟悉,也是可以很快地掌握 Perl 语言。<br><br>erl 作为编写 CGI 的语言虽然很好,但是对于复杂的网络应用就不是很有效了,这主要来源于 Apache 与 Perl 的配合。每一个 Perl 的 CGI 程序在被 Apache 调用执行的时候都必须开一个单独的进程来完成。而 Linux/UNIX 操作系统下,进程是一个非常消耗系统资源的实体,作为访问量巨大的网络服务器,如果只用 Perl 来完成 CGI 所需的功能将会使服务器不堪重负。所幸的是现在有一个 Apache 的专用模块,Emb-Perl,其语法与 Perl 几乎相同,但是他由于采用少量后台进程来循环供 Apache 使用,因此大大提高了运行效率。关于 Emb-Perl方面的知识在我们本次系列讲座的应用部分有专门的介绍,这里就不多谈了。<br><br>虽然 Perl 不是专门用来编写 CGI 的,而且 Perl 的功能远远超过编写 CGI 程序,但是 Perl 依然不失为一个优秀的 CGI 程序语言。而且许多人一开始接触 Perl 也是从 CGI 开始的,下面我们就来举几个小例子,来快速了解和体会 Perl 的 CGI 程序。<br><br><br><br><br>6.2    几个简单的 Perl CGI 程序<br>由于我们还没有讲解详细的 Perl 语法,所以下面讲解的例子可能会有一些不太明白的地方,不过没有关系,我们快速看几个 Perl 写的 CGI 程序的例子,获得一定的感性认识,等到这一讲结束后,相信同学们就可以弄清楚这些程序的含义了,而且也可以自己试着写几个 CGI 程序了。<br><br>用 Perl 来写 CGI,要求服务器必须已经配置好 Apache 和 Perl,关于这些服务器配置方面的问题同学们可以去听我们系列讲座应用部分的一些相关讲座,这里我们假定服务器已经配置妥当。<br><br>第一个例子是大家最常看到的计数器。我们用 vi 编辑如下这个程序(和 BASH 一样,除了 #&#33; 所在的第一行以外,所有以 # 开始到行尾的部分都是注释):<br><br>#&#33;/usr/bin/perl <br><br># 输出 HTML 说明信息,让浏览器知道这是一个 HTML 格式的文档。<br>print &quot;Content-type: text/html\n\n&quot;; <br># 打开文件 count.txt 供读取,count.txt 文件中存储了一个整数。<br>open(CNT,&quot;count.txt&quot;); <br><br># 读取 count.txt 文件中的整数,存放到变量 $count 中。CNT 相当于 C 语言中的文件句柄。<br>$count=&lt;CNT&gt;; <br># 如果该程序被执行,说明调用该程序的页面又被访问了一次,变量 $count 加 1。<br>$count ++; <br><br># 把加 1 后的结果,和访问者的 IP 地址输出给浏览器。<br>print &quot;你是第 $count 位访问者,来自 $ENV{&#39;REMOTE_ADDR&#39;} &lt;br&gt;&quot;; <br><br># 关闭 count.txt 文件<br>close(CNT); <br><br># 再打开另一个文件 count.old 用于永久保存加 1 后的计数值。(因为 $count 在程序执行结束后就没有了)<br>open(OLD ,&quot;&gt;count.old&quot;); <br># 将变量 $count,即加 1 后的结果写回 count.old 文件中。<br>print OLD $count; <br># 关闭 count.old 文件<br>close(OLD); <br><br># 执行 Shell 命令,将 count.old 文件复制成 count.txt 文件,此时这两个文件中都包含了最新的计数值。<br>`cp count.old count.txt`;<br><br># 退出该程序<br>exit;<br><br>在需要计数的页面中插入下面这行:<br><br>&#60;&#33;--#exec cgi=&quot;/cgi-bin/counter.pl&quot;--&#62;<br><br>并将页面的文件名从 xxx.html 改为 xxx.shtml。这样下次再访问这个页面的时候,就可以在相应位置看到有个整数每访问一次就会自动加一。<br><br>下面再来看一个稍微复杂一点的例子。<br><br>#&#33;/bin/usr/perl <br><br># 输出 HTML 语句头<br>print &quot;Content-type: text/html\n\n&quot;; <br>print &quot;&lt;TITLE&gt; Quiz &lt;/TITLE&gt;&quot;; <br>print &quot;&lt;H1&gt; 在线测验 &lt;/H1&gt;&quot;;<br><br># 调用 parse 函数<br>&amp;parse; <br><br># %ANSWER 是一个关联阵列 (以本表单为例 , 第一题答案是 A , 第二题答案是 C)一共有五题。<br>%ANSWER=(&quot;1&quot;,&quot;A&quot;,&quot;2&quot;,&quot;C&quot;,&quot;3&quot;,&quot;C&quot;,&quot;4&quot;,&quot;C&quot;,&quot;5&quot;,&quot;B&quot;); <br># 为 正确题数/错误题数 均赋初值为零。<br>$right=0; <br>$wrong=0; <br><br># 用 keys 这个函数将 FORM 的每个 KEY 取出存成一个阵列,再用 sort 这个函数来排序 (由小排到大) 。<br>foreach $Num (sort keys %FORM) { <br><br> # $FORM{$Num}所存放的是表单里 value 的值 <br> print &quot;第 $Num 题你所答的答案是:$FORM{$Num} &quot;; <br><br> # $ANSWER{$Num}所存放的是%ANSWER这个关联阵列由 $Num 所对应出来 A,C,C,C,B <br> print &quot;标准答案:$ANSWER{$Num} &lt;br&gt;&quot;; <br><br> # 计算答对和答错的题数。<br> if ($FORM{$Num} eq $ANSWER{$Num}) { <br>  $right++; <br> } else { <br>  $wrong++; <br> } <br>} <br><br>print &quot;&lt;p&gt;您总共答对:$right 题;答错:$wrong 题&lt;/p&gt;&quot;; <br><br>sub parse{ <br> read(STDIN, $buffer, $ENV{&#39;CONTENT_LENGTH&#39;}); <br> @pairs = split(/&amp;/, $buffer); <br><br> foreach $pair (@pairs){ <br>  ($name, $value) = split(/=/, $pair); <br>  $value =~ tr/+/ /; <br>  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack(&quot;C&quot;, hex($1))/eg; <br>  $FORM{$name} = $value; <br> } <br>} <br><br>这个例子在浏览器中的显示和执行结果是这样的。<br><br><br><br><br>6.3    CGI 中常用的环境变量<br>我们注意到在上面的例子中用到了 $ENV{&#39;CONTENT_LENGTH&#39;} 和 $ENV{&#39;REMOTE_ADDR&#39;} 这样的变量,这些变量被称为 WWW 服务的环境变量,就像我们在前面了解的 BASH 所用到的 Shell 环境变量 ${HOME} 等一样。WWW 服务中提供的变量还有很多,下面我们列出一些。<br><br><br>环境变量          意义 <br>SERVER_NAME CGI脚本运行时的主机名和IP地址. <br>SERVER_SOFTWARE 你的服务器的类型如: CERN/3.0 或 NCSA/1.3. <br>GATEWAY_INTERFACE 运行的CGI版本. 对于UNIX服务器, 这是CGI/1.1. <br>SERVER_PROTOCOL 服务器运行的HTTP协议. 这里当是HTTP/1.0. <br>SERVER_PORT 服务器运行的TCP口,通常Web服务器是80. <br>REQUEST_METHOD POST 或 GET, 取决于你的表单是怎样递交的. <br>HTTP_ACCEPT  浏览器能直接接收的Content-types, 可以有HTTP Accept header定义. <br>HTTP_USER_AGENT 递交表单的浏览器的名称、版本 和其他平台性的附加信息。 <br>HTTP_REFERER 递交表单的文本的 URL,不是所有的浏览器都发出这个信息,不要依赖它 <br>ATH_INFO 附加的路径信息, 由浏览器通过GET方法发出. <br>ATH_TRANSLATED 在PATH_INFO中系统规定的路径信息. <br>SCRIPT_NAME 指向这个CGI脚本的路径, 是在URL中显示的(如, /cgi-bin/thescript). <br>QUERY_STRING 脚本参数或者表单输入项(如果是用GET递交). QUERY_STRING 包含URL中问号后面的参数. <br>REMOTE_HOST 递交脚本的主机名,这个值不能被设置. <br>REMOTE_ADDR 递交脚本的主机IP地址. <br>REMOTE_USER 递交脚本的用户名. 如果服务器的authentication被激活,这个值可以设置。 <br>REMOTE_IDENT 如果Web服务器是在ident (一种确认用户连接你的协议)运行, 递交表单的系统也在运行ident, 这个变量就含有ident返回值. <br>CONTENT_TYPE 如果表单是用POST递交, 这个值将是 application/x-www-form-urlencoded. 在上载文件的表单中, content-type 是个 multipart/form-data. <br>CONTENT_LENGTH 对于用POST递交的表单, 标准输入口的字节数. <br><br> <br><br>6.4    关于 CGI 的更多内容<br>好了,我们已经看出来,用 Perl 写 CGI 并不困难,不过要想精通 Perl 的编程还的确不容易,而且 CGI 程序极易引发网络服务器的安全问题,这里有一篇关于 CGI 安全性的文章,有兴趣的同叙可以看看。 <br><br>下面我们就进入 Perl 语言的正式学习。 <br><br>                       
8#
发表于 28.11.2002 11:48:33 | 只看该作者
9#
 楼主| 发表于 28.11.2002 11:48:35 | 只看该作者
                          <br>7    Perl 的变量<br>简单变量 <br><br>数组 <br><br>关联数组 <br><br>各种运算符汇总 <br><br>7.1    简单变量<br>erl 的 Hello World 是怎么写的呢?请看下面的程序:<br><br>#&#33;/usr/bin/perl<br>print &quot;Hello World&quot;<br><br>这个程序和前面 BASH 的 Hello World 程序几乎相同,只是第一行换成了 #&#33;/usr/bin/perl ,还有显示的时候用的是 print,而不是 echo。有了前面 BASH 基础和 C 语言的基础,许多 Perl 的知识可以很容易的就看懂和记住,下面我们就从简单变量开始。<br><br>简单变量是标量,是 Perl 处理的最简单的数据类型。标量可以是数字(如2,3或2.5e6), 也可以是字符串。Perl 中的标量变量以美元符号 &quot;$&quot; 和一个字母开始,后面可以跟字母、数字和下划线,Perl 的变量区分大小写,因此 $a 和 $A 是代表不同的变量。和 BASH 中不同的是 Perl 语言中的变量即使是在最初赋值的时候也必须在变量前面加上 &quot;$&quot; 符号,而且 Perl 不要求 &quot;=&quot; 左右必须没有空格。<br><br>虽然 Perl 中和 BASH 一样,没有变量类型的概念,我们还是可以把简单变量分为数值型和字符串型来理解。在赋值时,如果是赋值成字符串,则需要在字符串两边加上双引号(或单引号);如果是数值则就不用了,而且 Perl 中还可以接受8/16(以0开头/以0x或0X开头)进制的整数,还可以接受如 2.5,-6.3e5,-2.3-e6 这样的浮点数。关于简单变量举例如下:<br><br>$a=23; <br>$a = &quot;hello&quot;; <br>$a = 010;(表示十进制的 8)<br>$a = 0x10;<br>$a = 0X10;<br><br>和 C 语言类似,在双引号之中可以用反斜杠表示一些特殊转义字符,见下表:<br><br>结 构 含 义 <br>\n 换行 <br>\r 回车 <br>\t 水平置表符 <br>\f 换页符 <br>\b 退格 <br>\v 垂直置表符 <br>\a 响铃 <br>\e Esc <br>\007 任一八进制ASCII值(这里007表示bell) <br>\x7f 任一十六进制ASCII值 <br>\cC 任一“控制”字符 <br>\\ 反斜杠 <br>\&quot; 双引号 <br>\l 下一字母小写 <br>\L 以后所有字母小写直到\E <br>\u 下一字母大写 <br>\U 以后所有字母大写直到\E <br>\E 结束\L和\U <br><br>另外在 Perl 语言里,我们常会看到 my 这样的变量定义,如:<br><br>my $a = &quot;local var&quot;;<br><br>这表示 $a 是一个程序块的局部变量。<br><br> <br><br>7.2    数组<br>数组是标量数据的有序列表。数组可以含从 0 个元素大小 直到 你计算机内存可以支持的大小。数组用括号内以逗号分隔的一系列元素来表示。如:<br><br>@a=(1,2,3,4,5)<br>@a=(&quot;aka&quot;,1974,173.5)<br><br>在 Perl 中对数组变量和前面的简单变量的存储是在不同的空间中,对数组的引用需要在变量前加 &quot;@&quot; 符号。<br><br>数组的赋值由下面几种用法需要注意:<br><br>@a=(1,2,3); # 初始化一个整数数组。 <br>$a=@a; # 这里表示将数组 @a 的长度赋给 $a,此时 $a 和 @a 不是一个变量,他们不在一个存储空间里,引用时不会发生混淆。 <br>($a, $b, $c)=(1,2,3); # 这里表示将 1 赋给 $a;2 赋给 $b;3 赋给 $c; <br>@a=(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;); # 初始化一个字符串数组。 <br>@b=@a; # 表示把数组 @a 拷贝一份给数组 @b,@a 与 @b 不享有共同的存储空间,他们彼此分离。 <br>@c=(@a,@<!--emo&B)--><img src='http://bbs.kaiyuan.info/html/emoticons/cool.gif' border='0' valign='absmiddle' alt='cool.gif'><!--endemo-->; # 表示数组 @c 拥有 @a 和 @b 的所有元素,仍然是一维数组,而不是发生了嵌套。 <br>($a,@<!--emo&B)--><img src='http://bbs.kaiyuan.info/html/emoticons/cool.gif' border='0' valign='absmiddle' alt='cool.gif'><!--endemo-->=@a; # 表示变量 $a 等于数组 @a 的第一个元素,@b 拷贝了 @a 的剩余元素。 <br>@a=(); # 表示产生或清空一个数组。 <br>($a)=@b; 变量 $a 等于数组 @b 的第一个元素的值。 <br>@b 引用数组 @b 的第 i 个元素。 <br>$b 如果 b 表示一个数组的话,其含义同上。 <br>$a[i,j]=[x,y] 将数组 @a 的第 i 和第 j 个元素赋值为 x 和 y。 <br>@a[i,j]=@a[j,i] 将数组 @a 的第 i 和第 j 个元素的值互相交换。 <br><br> <br><br><br><br><br>7.3    关联数组<br>关联数组是 Perl 语言中特有的一种数据结构,是一个功能强大的数组,他与普通数组的不同在于关联数组不是通过整数下标来索引,而是通过“键值”进行索引。使用关联数组需要在变量前面加上 &quot;%&quot; 号,关联数组的格式如:<br><br>ARRAY=(key1,value1,key2,value2,key3,value3); <br><br>上面每个 key 都对应着一个 value。关联数组是存在在另外一个存储空间中,不和简单变量以及数组相混淆。<br><br>对关联数组的操作有如下规则: <br><br>在关联数组中增加、更改一对数据:ARRAY={key}=value; 在关联数组ARRAY中加上一对 key-value,要在关联数组名称前加上 $ 号,而且 key 的名称要在 {} 符号之间,最后再指定 key 所对应的 value 值。如果在这个关联数组中已经有这个 key 了.就会更改这个 key 所对应的 value 。 <br><br><br>keys(%array) 操作符可生成由关联数组 %array 中的所有当前关键字组成的列表。即返回奇数号元素(第1,3,5,7...个)的列表。<br><br><br>values(%array) 操作符返回由关联数组 %array 中所有当前值组成的列表,即返回偶数个列表。<br><br><br>echo(%array) 操作符返回由 关键字/值对 构成的元素对列表。对同一数组再进行此操作时返回下一对值直至结束。若没有更多的对时,echo() 返回空表。 (这在打印全部列表中很有用) <br><br><br>删除一对在关联数组中的数据:delete $ARRAY{key}; delete 是 Perl 所提供的函数,作用是删除关联数组中的一个 key 以及这个 key 所对应的 value。使用方法是在 delete 函数之后,指定关联数组中要删除的 key 名称。 <br>下面是一些关联数组操作的例子:<br><br>%fred=(one,&quot;aka&quot;,two,&quot;free&quot;); $a=$fred{one}; # $a等于&quot;aka&quot;<br> <br>$b=$fred{two}; # $b等于&quot;free&quot;<br> <br>$fred{two}=&quot;yes&quot;; # %fred=(one,&quot;aka&quot;,two,&quot;yes&quot;)<br> <br>@index=keys(%fred); # @index=(one,two)<br> <br>@content=values(%fred); # @content=(&quot;aka&quot;,&quot;yes&quot;)<br> <br>($index,$content)=echo(%fred); # 此时 $index 的值为 one,$content 的值为 &quot;aka&quot;,再执行一次 $index 为值为 two,$name 的值为 &quot;yes&quot; <br>@a=%fred; # 将关联数组 fred 指定给数组 a,这时 @a=(one,&quot;aka&quot;,two,&quot;yes&quot;)<br> <br>%b=@a; # 将数组 a 指定给关联数组 b,这时 %b=(one,&quot;aka&quot;,two,&quot;yes&quot;)<br> <br>delete $fred{one}; # 将关联数组中 key 值为 one 的一对 key-value 删除,这时 %fred=(two,&quot;yes&quot;) <br>%x=(); # 把 %x 关联数组置空<br> <br><br>  <br><br>7.4    各种运算符号汇总<br>赋值(Assignment)运算符<br>算术(Arithmetic)运算符<br>数值(Numeric Values)关系运算符<br>字符串(String Values)关系运算符<br>逻辑(Logical)运算<br>其它常用的运算符<br>常用的文件数据(File Test)运算符 <br><br>  赋值(Assignment)运算符<br><br>--------------------------------------------------------------------------------<br><br> <br>符号 范例 说明 <br>= $x=$y; 将$x的值指派给$y <br>+= $x+=$y;<br>$x=$x+$y; 将$x加$y之后再指派给$x <br>-= $x-=$y;<br>$x=$x-$y; 将$x减$y之后再指派给$x <br>*= $x*=$y;<br>$x=$x*$y; 将$x乘$y之后再指派给$x <br>/= $x/=$y;<br>$x=$x/$y; 求出$x除以$y之后的商数,再指派给$x <br>**= $x**=$y;<br>$x=$x**$y; 将$x乘上$y次方之后再指派给$x <br>%= $x%=$y;<br>$x=$x%$y; 求出$x除以$y的余数以后,再指派给$x  <br>.= $str1.=$str2;<br>$str1=$str1.$str2; 将$str1这个字符串再加上$str2这个字符串之后,再指派给$str1这个字符串 <br>x= $strx=$y;<br>$str=$strx$y; 重复$str字符串$y次,并反结果指派给str这个字符串 <br><br>算术(Arithmetic)运算符 <br><br>--------------------------------------------------------------------------------<br>   <br>符号 范例 说明 <br>+ $z=$x+$y 将$x和$y相加之后,再将结果指派给$z <br>- $z=$x-$y 将$x减掉$y之后,再将结果指派给$z <br>* $z=$x*$y 将$x和$y相乘之后,再将结果指派给$z <br>/ $z=$x/$y 将$x除以$y之后,再将商数指派给$z <br>% $z=$x%$y 将$x除以$y之后,再将余数指派给$z <br>** $z=$x**$y 将$x乘以$y之后,再将结果指派给$z <br>++ $x++;++$x; 如同$x=$x++1;将$x加一以后再将结果指派给$x <br>-- $x--;--$x; 如同$x=$x-1;将$x减一以后再将结果指派给$x <br>. $z=$x.$y; 将$x字符串和$y字符串连接之后,再将结果指派给$z <br><br>数值(Numeric Values)关系运算符<br><br>--------------------------------------------------------------------------------<br><br> <br>符号 范例 说明 <br>&gt; $x&gt;$y 如果$x大于$y,返回1的值,否则返回0 <br>&gt;= $x&gt;=$y 如果$x大于等于$y,返回1的值,否则返回0 <br>&lt; $x&lt;$y 如果$x小于$y,返回1的值,否则返回0 <br>&lt;= $x&lt;=$y 如果$x小于等于$y,返回1的值,否则返回0 <br>== $x==$y 如果$x等于$y,返回1的值,否则返回0 <br>&#33;= $x&#33;=$y 如果$x不等于$y,返回1的值,否则返回0 <br>&lt;=&gt; $x&lt;=&gt;$y 如果$x大于$y,返回1的值,如果$x等于$y,否则返回0;&amp;127;如果 $x小于$y,则返回-1的值 <br><br>字符串(String Values)关系运算符<br><br>--------------------------------------------------------------------------------<br><br> <br>符号 范例 说明 <br>gt $str1 gt $str2 如果$str1大于$str2,返回1的值,否则返回0 <br>ge $str1 ge $str2 如果$str1大于等于$str2,返回1的值,否则返回0 <br>lt $str1 lt $str2 如果$str1小于$str2,返回1的值,否则返回0 <br>le $str1 le $str2 如果$str1小于等于$str2,返回1的值,否则返回0 <br>eq $str1 ep $str2 如果$str1等于$str2,返回1的值,否则返回0 <br>ne $str1 ne $str2 如果$str1不等于$str2,返回1的值,否则返回0 <br>cmp $str1 cmp $str2 如果$str1大于$str2,返回1的值,如果$str1等于$str2,返回0,如果$str1小于$str2,则返回-1的值 <br>逻辑(Logical)运算 <br><br>--------------------------------------------------------------------------------<br><br>1) $x &amp;&amp; $y(And)<br><br>$x    $y    结果<br><br>真(True) 真(True) 真(True) <br><br>真(True) 假(False) 真(True) <br><br>假(False) 真(True) 假(False)<br><br>假(False) 假(False) 假(False)<br><br>2) $x || $y(Or)<br><br>$x    $y    结果<br><br>真(True) 真(True) 真(True) <br><br>真(True) 假(False) 真(True) <br><br>假(False) 真(True) 真(True)<br><br>假(False) 假(False) 假(False)<br><br>3) $x(Not)<br><br>$x    结果<br><br>真(True) 假(False)<br><br>假(False) 真(True) <br> <br><br>其它常用的运算符 <br>--------------------------------------------------------------------------------<br><br>指令:..区块运算符(Range Operator)<br><br>说明:这个运算符是 Perl 语言中特有的运算符,是一个很实用的运算符。<br><br>范例:<br><br>@digits=(1..9); # 此时 @digits=(1,2,3,4,5,6,7,8,9);<br>@digits=(&#39;01&#39;..&#39;05&#39;); # 此时 @digits=(01,02,03,04,05);<br>@char=(&#39;A&#39;..&#39;E&#39;); # 此时 @char(&#39;A&#39;,&#39;B&#39;,&#39;C&#39;,&#39;D&#39;,&#39;E&#39;,);<br>@total=(1..3,&#39;A&#39;..&#39;B&#39;); # 此时 @total=(1,2,3&#39;A&#39;,&#39;B&#39;);<br><br>指令: 条件运算符(Conditional Operator)<br><br>说明: (判别运算式? 运算式1: 运算式2)这个语法的意义和C语言一样:如果判别运算式的值是真(True)的话,则做运算式 1 的运算;如果判别运算式是假(False)的话,则做运算式 2 的运算。<br><br>范例:<br><br>$price = ($age&gt;60)? 100:200;<br>如果 $age 大于60的话,则$price等于100,否则$price等于200。<br> <br><br>常用的文件数据(File test)运算符<br><br>--------------------------------------------------------------------------------<br><br> <br>范例 说明 <br>-r $file 如果 $file 是可读取的话,返回 1 <br>-w $file 如果 $file 是可写入的话,返回 1 <br>-x $file 如果 $file 是可执行的话,返回 1 <br>-e $file 如果 $file 存在的话,返回 1 <br>-s $file 返回 $file 的文件大小(bytes) <br>-f $file 如果 $file 是正常文件的话,返回 1 <br>-T $file 如果 $file 是文本文件的话,返回 1 <br>-B $file 如果 $file 是Binary文件的话,返回 1 <br>-M $file 返回 $file 文件最后一次更改时间到现在的日期数 <br><br>                       
10#
 楼主| 发表于 28.11.2002 11:49:08 | 只看该作者
                          <br>8    Perl 的简单语法(与 C 语言的异同)<br>基本输入输出 <br><br>分支循环控制结构 <br><br>函数 <br><br>常用系统调用 <br><br>文件操作 <br><br>进程管理 <br><br>7.1    基本输入输出<br>在 BASH 脚本程序中,我们用 read var 来实现从键盘的输入,用 echo $var 来实现输出。那么在 Perl 中将有一点变化。Perl 中将标准输入用关键词 &lt;STDIN&gt; 表示;标准输出用 &lt;STDOUT&gt; 表示,标准错误输出用 &lt;STDERR&gt; 表示。故而从标准输入读取数据可以写成:<br><br>$var=&lt;STDIN&gt;; # 读取一行输入,并存入变量 $var 中。<br>@var=&lt;STDIN&gt;; # 读取多行输入,并存入数组 @var 中。<br><br>在 Perl 语言中,变量 $_ 是许多操作符的缺省变量。因此如果需要读入许多行并对每行分别处理一般这样写:<br><br>   while($_=){ <br>    chop($_); # chop 调用用于去掉 $_ 变量中的最后一个字符(换行符)。<br>    # 处理$_(每一行)<br>   } <br><br>或者可以简写为:<br><br>   while(){ <br>    chop; # 等同于chop($_) <br>    # 处理$_(每一行) <br>   }<br><br>如果 &lt;&gt; 括号之间没有任何字符,则表示从命令行所指示的文件中读取数据,看下面这个例子(read.pl):<br><br>   #&#33;/usr/bin/perl; <br><br>   while(&lt;&gt;){ <br>    print $_; <br>   }<br><br>如果在命令行输入 $ perl read.pl read.pl 。这个程序将在屏幕上打印出文件 read.pl 的每一行。<br><br>在前面的例子中我们已经看见,Perl 语言中向标准输出输出数据可以用 print 语句。我们在 print 语句中可以输出多个变量,变量之间用 &quot;,&quot; 分隔开来。如下面的例子:<br><br>   print 3,45*2,&quot;hello&quot;,2+2;<br><br>上面的输出语句将给出 &quot;390hello4&quot; 的输出结果。<br><br>除了 print 语句以外,Perl 中还提供了一个 printf 语句用于标准输出,不过 printf 更接近于 C 语言的 printf 函数,可以进行格式化的输出,如:<br><br>   printf &quot;%10s% 8d%8.2f\n&quot;,$a,$b,$c;<br>   printf(&quot;%10s% 8d%8.2f\n&quot;,$a,$b,$c); # 加上括号的 C 语言写法也是可以的。<br><br><br>另外 print 和 printf 在输出数组变量的时候也是不同的,如下例:<br><br>@a = (1 , 2, 3); <br>printf @a; <br>print &quot;\n&quot;; <br>print @a; <br>print &quot;\n&quot;;<br><br>输出的结果是:<br><br>1<br>123<br><br>如果在 @a 两边加上 &quot;&quot; ,则输出就都是 123了。<br><br> <br><br>7.2    分支循环控制结构<br>if 语法<br>erl 语言的 if...then...else... 语句结构和 C 语言非常相似,该结构一共有三种变种,分别如下:<br><br>if 语法 1:<br><br>if(判别运算式)<br>{ <br>  表达式为真时的语句块; <br>}<br><br>或写成:表达式为真时的语句 if (判别运算式);<br><br>实例为:print &quot;您的分数及格了&#33;\n&quot; if ($score&gt;=60);<br><br>if 语法 2:<br><br>if(判别运算式一){ <br>  判别式一为真时的语句块;<br>}else{ <br>  判别式一为假时的语句块;<br>}<br><br>if 语法 3:<br><br>if (判别运算式一)<br>{ <br>  判别式一为真时的语句块;<br>}elsif(判别运算式二){ <br>  判别式二为真时的语句块;<br>}elsif(判别运算式三){ <br>  判别式三为真时的语句块;<br>}else{ <br>  所有判别式为假时的语句块;<br>}<br><br>unless 语法<br>unless的含义就是说“如果判别式不为真,就执行...”。<br><br>unless 语法 1:<br><br>unless(判别运算式) { <br>  判别式为假时语句块;<br>}<br><br>或写为:判别式为假时语句 unless (判别运算式);<br><br><br>unless 语法 2:<br><br>unless(判别运算式)<br>{<br>  判别式为假时语句块;<br>}else{ <br>  判别式为真时语句块;<br>}<br><br>进阶技巧:&quot;&amp;&amp;&quot;、&quot;||&quot; 及 &quot;? :&quot; <br>这些符号看上去像标点符号,或是表达式的一部分。和 C 语言中一样,他们在 Perl 语言中也可作为控制结构,而且更简洁,只是可读性差了很多。 <br><br>比如说:<br><br> if (判别表达式) {为真时语句块};<br><br>也可以写为:<br><br> 判别表达式 &amp;&amp; 为真时的语句块 <br><br><br>同样道理,unless(this){that} 可替换为 this||that。<br><br>? : 则可以这样使用:<br><br>exp1?exp2:exp3<br><br>这个式子表示:如果 exp1 为真则求 exp2 的值,否则求 exp3 的值。<br><br>while 循环语法<br>erl 语言中 while, do...while, for, until, foreach 均可以用于实现循环结构,循环中还可以用 last,next,redo 等操作符进行控制。下面我们先介绍 while 语法。<br><br>while(判别运算式) { <br>  程序叙述区块;<br>}<br><br>上个语法在Perl中也可以写成: 程序叙述区块 while(判别运算式);<br><br>do...while 循环语法<br>do<br>{ <br>  程序叙述区块;<br>}while(判别运算式);<br><br><br>在 while 和 do while 循环最大的区别是在 do while 循环中,循环体至少会被执行一次。<br><br>until 循环语法<br>until(判别运算式)<br>{ <br>   程序叙述区块;<br>}<br><br>上个语法在Perl中也可以写成: 程序叙述区块 until (判别运算式);<br><br>do...until 循环语法<br>do{ <br>   程序叙述区块; <br>}until (判别运算式);<br><br>for 循环语法<br>for (初始化运算式;判别运算式;循环过程运算式)<br>{ <br>  程序叙述区块;<br>}<br><br>或者<br><br>for $variable(@array)<br>{ <br>  程序叙述区块;<br>}<br><br><br>第二个语法中如果把 $variable 变量省略的话,就会将数组 @array 的元素一个一个指定给 $_ 这个变量,这是比较精简的写法。其中第一个语法更接近于 C 语言的语法。<br><br>foreach 循环语法<br>foreach $variable(@array)<br>{ <br>  程序叙述区块;<br>}<br><br>如果把$variable变量省略的话,就会将数组@array的元素一一指定给$_这个内定的输出变量.<br><br>last 退出循环语法<br>范例:<br><br>for($i=1;$i&lt;=10;$i++)<br>{ <br>  last if ($i==5); # 如果 $i 等于5的话就退出 for 循环<br>  print&quot;$i\n&quot;;<br>}<br><br>next 继续循环语法<br>范例:<br><br>for($i&lt;=10;$i++)<br>{ <br>  # 如果是 2 的倍数的话,就到循环的下一个陈述<br>  next if($i%2)==0)<br>    print&quot;$i是一个奇数&#33;\n&quot;;<br>}<br><br> <br><br><br><br><br>7.3    函数<br>erl 语言中有两种函数,一种是 Perl 自带的一些实用系统函数,如文件打开函数 open 等;另一种是用户自定义的函数,用户通过自己定义函数可以使得程序的结构化更加清晰。<br><br>用户函数又称子程序(Subroutine),在 Perl 中用下面的结构来定义用户函数:<br><br>  sub 子程序名{<br>     语句块;<br>  }<br><br>这里的子程序名与变量的取名规则类似。<br><br>与 BASH 程序不同,Perl 中的用户函数的定义可以位于程序的任何位置,比如说放在文件的未尾,而并不需要放在调用该函数的代码之前。如果两个子程序使用了相同的程序名,位置靠后的子程序将覆盖前面子程序。<br><br>需要注意的是用户函数中的变量默认为全局变量,并不是像 C 语言中那样是局部变量,Perl 函数中的变量可以被其他程序段共享。如果希望定义局部变量,可以用下面两种方法来实现: <br><br>local($a);<br>my $a;<br><br>另外用户函数的调用:通过在子程序前加“&amp;”符号才可以,函数可在任一表达式内被调用。函数调用可以嵌套,即子程序中可以再调用另外的子程序,即可以程序员可以用 Perl 写出具有递归特性的代码。<br><br>调用用户函数产生的结果称为返回值(return value)。返回值是每次函数被执行时,最后一个被执行到的表达式的计算结果。如: <br><br>sub add_a_b{<br>      $a+$b;<br>}<br><br>函数最后一条表达式为 $a+$b,故返回值为 $a+$b 的计算结果。以下是调用情况:<br><br>$a = 5;<br>$b = 6;<br>$c = &amp;add_a_b; # $c 的值为 11<br>$d = 5 * &amp;add_a_b; # $d 的值为 5*11,即 55<br><br>还有一个问题是,在 Perl 程序中如何向函数中传递参数呢?这是可以实现的,调用函数时,可以将参数依次放在函数名后面的 &quot;()&quot; 中,而在函数体中,系统默认数组 @_ 中就按同样顺序存放着所有的参数。我们可以访问 @_ 变量,从而确定参数的个数及其数值。<br><br>仍以加法函数为例:<br><br>sub add_a_b{<br>  $_[0]+$_[1];<br>}<br><br>$c=&amp;add_a_b(5,6); #$c的值为11<br>$d=5*&amp;add_a_b(2,3); #d的值为5*5即25<br><br>更为奇特的是,这种方式可以实现变参数传递,即参数个数不确定的传递。C 语言也可以实现这种传递,如我们熟悉的 printf 函数,只是他们的实现机制不太一样,C 更深奥一些,此处就不多解释了。 <br><br>sub add_all{<br>  $sum=0; #将sum初始化<br>foreach $_(@_) { #遍历参数列表<br>  $sum+=$_; #累加每个元素<br>}<br>  $sum; #返回sum即总和的值<br>}<br><br>$a=&amp;add_all(3,4,5); #$a的值为3+4+5即12<br>$d=2*&amp;add_all(1,2,3,4,5); #d的值为2*15即30<br><br><br><br><br><br>7.4    常用系统调用<br>下面将介绍一些 Perl 自身提供的一些标准系统函数,这些函数包括: print 、printf 、chop 、split 、keys 、values 、reverse 、sort 、length 、substr 、index 、push 、pop 、unshift 、shift 、join 、grep 、hex 、rand 、localtime 、die 、open 、close 、pack 、read 、exit。下面就来分别介绍他们。 <br><br>  <br><br><br>--------------------------------------------------------------------------------<br><br>指令:print<br>语法:print Filehandle LIST<br>说明:这个 Filehandle 可以看作在 I(INPUT)/O(OUTPUT) 之间的一个桥梁,可以利用 FILEHANDLE 来做出数据读入写出的动作。STDIN 是代表从哪里输入数据,例如从电脑的键盘输入;STDOUT是代表从哪里输出数据,例如从电脑的屏幕输出;STDERR 是代表从哪里输出错误的数据,例如从电脑的屏幕输出。而在PERL语言中有三个标准FILEHANDLE: <br>1. STDIN(标准输入):是代表 STDIN 的 FILEHANDLE <br>2. STDOUT(标准输出):是代表 STDOUT 的 FILEHANDLE <br>3. STDERR(标准错误输出):是代表 STDERR 的 FILEHANDLE <br>如果要使用其他 FILEHANDLE 的时候,就要先用 OPEN 这个函数来打开一个 FILEHANDLE,我们可以用 PRINT 这个函数将 LIST 中的数据输出给 FILEHANDLE。<br><br>  语法: print LIST <br>说明: 如果省略 Filehandle 的话,就会把 Filehandle 默认为 STDOUT。也就是会将 LIST 的数据内容显示在终端屏幕上。<br><br>语法: print<br>说明: 同时省略 Filehandle 和 LIST 的话,就会以 STDOUT 为 Filehandle,并会输出 $_ 这个系统内部变量的数据内容。如果 $_ 变量是一个空字符串的话,就会显示出一个空字符串。<br><br><br><br>--------------------------------------------------------------------------------<br><br>指令: printf<br>语法: printf Filehandle LIST<br>说明: 在 Perl 语言中也提代 C 语言中 printf 的语法,用法和 C 语言中的用法一模一样。如果把 Filehandle 省略的话,也一样会把 STDOUT 当成是默认的 Filehandle。<br>示例:<br><br>printf(&quot;chomod %d %s\n&quot;,&quot;711&quot;&quot;cgi&quot;); 会将chmod 711 cgi加上换行显示于屏幕上。 <br><br><br>--------------------------------------------------------------------------------<br><br>指令:chop 语法:chop($url)<br>说明:把最后一个字符删除。<br>示例:<br>$url=&quot;www.aka.org.cn/; chop($url); <br>这时$url=&quot;www.aka.org.cn&quot; 还可以简写成 chop($url=&quot;www.aka.org.cn/&quot;); chop 函数一般用于去掉从键盘读入数据中的最后一个换行符。<br><br><br>--------------------------------------------------------------------------------<br><br>指令:split<br>语法:split(/pattern/,$text,limit) 其中/pattern/是文字处理的模式,而limit是代表要分割的个数,一般可以省略。<br>说明:用一个指定的文字处理模式来分割 $text 字符串。<br>示例:<br>$text=&quot;Michael,Gevin,Mike&quot;; @name=split(/,/,$text); # 这时 @name=(&quot;Michael&quot;,&quot;Gevin&quot;,&quot;Mike&quot;); <br>@name=split(/,/,$text,2); # 这时 @name=(&quot;Michael&quot;,&quot;Gevin&quot;);<br>在传送CGI应用程序数据的时候会先将数据编码,其中会将FORM中第个数据字段 的数据内容用&amp;这个符号隔开,所以在解码的时候就要以 &quot;&amp;&quot; 这个符号为分割的字符,将每个数据字段分割出。而数据字段的名称和这个数据字段的值是用=这个符号来隔开,如果想取得数据字段的名称和所对应的值的话,就用要 &quot;=&quot; 这个符号来分割数据字段,<br><br><br>--------------------------------------------------------------------------------<br><br>指令:keys<br>语法:keys(%array)<br>说明:取出关联数组 %ARRAY 中全部的 key。<br>示例:<br>%NAME=(1,&quot;mike&quot;,2,&quot;michael&quot;); @readkey=keys(%NAMES); # 这时 @readkey=(1,2); <br><br><br>--------------------------------------------------------------------------------<br><br>指令:values<br>语法:values(%array)<br>说明:取出关联数组 %ARRAY 中全部的 value。<br>示例:<br>%NAMES=(1,&quot;mike&quot;,2,&quot;michael&quot;); @readval=values(%NAMES); #这时 @readval=(&quot;mike&quot;,&quot;michael&quot;); <br><br><br>--------------------------------------------------------------------------------<br><br>指令:reverse<br>语法:reverse(@array)<br>说明:将数组 @array 中的元素由后到前重新排列。<br>示例:<br>@back=(&quot;A&quot;,&quot;B&quot;,&quot;C&quot;,&quot;D&quot;,&quot;E&quot;); @back=reverse(@back); # 这时 @back=(&quot;E&quot;,&quot;D&quot;,&quot;C&quot;,&quot;B&quot;,&quot;A&quot;); <br><br><br>--------------------------------------------------------------------------------<br><br>指令:sort<br>语法:sort(@array)<br>说明:将数组中的元素由小到大排序,如果要由大到小排序的话,要加上reverse这个函数。<br>示例:<br>@abc=(&quot;d&quot;,&quot;b&quot;,&quot;c&quot;,&quot;a&quot;); @abc=sort(@abc); # 这时 @abc=(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;,&quot;d&quot;);<br>@abc=(reverse sort@abc); # 这时@abc=(&quot;d&quot;,&quot;c&quot;,&quot;b&quot;,&quot;a&quot;); 这个语法也可以写成 @abc=(reverse sort(@abc));<br>@number=(5,2,10); @number=sort(@number); <br># 上面示例用sort函数来排序数值的时,会出差错,因此要用下面到下面这一句。 <br>@number=(sort{$a&lt;=&gt;$b}@number); # 这时 @number=(2,5,10); <br><br><br>--------------------------------------------------------------------------------<br><br>指令:length<br>语法:length($string)<br>说明:求出字符串$string的字节(bytes)值。<br>示例:<br>$string=&quoterl5&quot;; $size=length($string); # 这时 $size=5; <br><br><br>--------------------------------------------------------------------------------<br><br>指令:substr<br>语法:substr($string,offset,length) offset代表起始字符的位置,length代表引用的字符串长度,如果省略length则代表从起始值到字符串的最后一个字符长度。而offset如果是负值的话,就会从字符串右边开始指定字符。<br>示例:<br>$s=substr(&quot;perl5&quot;,2,2); # 这时 $s=&quot;rl&quot;;<br>$s=substr(&quot;perl5&quot;,2); # 这时 $s=&quot;rl5&quot;;<br>$s=substr(&quot;perl5&quot;,-2,2); # 这时 $s=&quot;er&quot;; <br><br><br>--------------------------------------------------------------------------------<br><br>指令:index<br>语法:index($string,$substring,position) $substring是要寻找的字符;position代表从哪一个位置开始寻找,假如省略position就从头开始找起。<br>说明:返回所要找寻的字符在一字符串$string中的位置,如果在字符串中找不到字符的话,则会返回-1这个 值。<br>示例:<br>$s=index(&quot;perl5&quot;,&quot;p&quot;); # 这时 $s=0<br>$s=index(&quot;perl5&quot;,&quot;l&quot;,2); # 这时 $s=3<br>$s=index(&quot;perl5&quot;,&quot;perl&quot;); # 这时 $s=-1 <br><br><br>--------------------------------------------------------------------------------<br><br>指令:push<br>语法:push(@array,$string)<br>说明:在数组@array的最后附加新的元素 ($string)到数组@array中。<br>示例:<br>@array=(&quot;one&quot;,&quot;two&quot;); push(@array,&quot;three&quot;); # 这时 @array=(&quot;one&quot;,&quot;two&quot;,&quot;three&quot;) <br><br><br>--------------------------------------------------------------------------------<br><br>指令:pop<br>语法:pop(@array)<br>说明:将数组(@array)的最后一个元素删除,并将删除的元素返回。<br>示例:<br>@array=(&quot;one&quot;,&quot;two&quot;); $rm=pop(@array); # 这时 @array=(&quot;one&quot;);而$rm=&quot;two&quot;; <br><br><br>--------------------------------------------------------------------------------<br><br>指令:unshift<br>语法:unshift(@array,$string) <br>说明:在数组@array的第一个元素前附加新的元素$string到数组@array中。 <br>示例:<br>@array=(&quot;one&quot;,&quot;two&quot;); unshift(@array,&quot;three&quot;); # 这时 @array=(&quot;three&quot;,&quot;one&quot;,&quot;two&quot;) <br><br><br>--------------------------------------------------------------------------------<br><br>指令:shift<br>语法:shift(@array)<br>说明:将数组@array的第一个元素删除,并将删除的元素返回。<br>示例:<br>@array=(&quot;one&quot;,&quot;two&quot;); @rm=shift(@array); # 这时 @array=(&quot;two&quot;);而$rm=&quot;one&quot;; <br><br><br>--------------------------------------------------------------------------------<br><br>指令:join<br>语法:join($string,@array)<br>说明:在一数组@array的元素之间加上一指定的字符$string,并将结果返回。<br>示例:<br>@array=(&quot;one&quot;,&quot;two&quot;,&quot;three&quot;);<br>$total=join(&quot;:&quot;,@array); 这时 $total=&quot;one:two:three&quot;; <br><br><br>--------------------------------------------------------------------------------<br><br>指令:grep<br>语法:grep(/pattern/,@array)<br>说明:将合文字处理模式(regular expression)的数组元素找出来。<br>示例:<br>@array=(&quot;one&quot;,&quot;on&quot;,&quot;in&quot;);<br>$count=grep(/on/,@array); # 这时 $count=2<br>@result=grep(/on/,@array); # 这时 @result=(&quot;one&quot;,&quot;on&quot;); <br><br><br>--------------------------------------------------------------------------------<br><br>指令:hex<br>语法:hex($string)<br>说明:将十六进制的数值转成十进制。<br>示例:<br>$decimal=hex(&quot;ff&quot;); 这时 $decimal=255; <br><br><br>--------------------------------------------------------------------------------<br><br>指令:rand<br>语法:rand($interger)<br>说明:常和函数srand搭配来取得一随机数,如果没有先宣告stand函数的话,则取出的常数值是一个固定值。这个语法会返回一个介于 0 和$interger之间的数值,如果$interger省略的话,则会返回一个介于 0 和 1 的数值。<br>示例:<br>srand; # 要先调用一次srand函数,才能产生随机数的效果<br>$int=rand(10); # $int的值会大于 0 而且小于 10 ,如果希望产生的乱数是整数的话,就要再加上int 这个函数,如下<br>$int=int(rand(10)); # $int的值是一个整数,且值在 0 和 9 之间 <br><br><br>--------------------------------------------------------------------------------<br><br>指令:localtime<br>语法:localtime(time)<br>说明:可返回九个有关时间的元素,在写CGI应用程序的时候常会用到系统的时间,所以在此会详细介绍这个函数的用法。<br>示例: <br>($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); <br>其中: $sec 代表秒数 [0,59]、$min 代表分数 [0,59]、$hour 代表小时数 [0,23]、$mday 代表是在这个月的第几天 [1,31]、$mon 代表月数 [0,11] 因此要将 $mon 加 1 之后,才能符合实际情况、$year 从 1990 年算起的年数、$wday 从星期六算起,代表是在这周中的第几天 [0-6]、$yday 从一月一日算起,代表是在这年中的第几天 [0,366]、$isdst 只是一个 flag 知道这些变量之后,就可以在 CGI 应用程序中拿来应用了。<br>此外,也可以用下面这一行指令在 UNIX 系统下取得系统的时间。为了避免错误发生,最好用绝对路径的方法来取得系统时间,如果绝对路径不清楚的话可以用 &quot;which data&quot; 这个指令来得知。$data=&#39;/usr/bin/data&#39;; 而在 Perl 5 版本中,也可以用下面这一行指令来取得系统时间。 $data=localtime(time); <br><br><br>--------------------------------------------------------------------------------<br><br>指令:die<br>语法:die LIST<br>说明:会把LIST字符串显示出来,并退出程序。常常和 $&#33; 这个代表错误信息变量一起使用。<br>示例:<br>open(FILE,&quot;$filename&quot;)||die &quot;不能打开文件$&#33;\n; # 如果打开文件失败的话,就会显示出错误的信息,之后再退出程序。 <br><br><br>--------------------------------------------------------------------------------<br><br>指令:open<br>语法1:open(filehandle,&quot;$filename&quot;) 其中 $filename 是一个指定打开的文件名。<br>说明:这是一个很常用的函数,可用于文件的打开(read only)。<br>示例:<br>$filename=&quot;usr/abc.txt&quot;;<br>open(FILE,&quot;$filename&quot;)||die&quot;不能打开文件$filename\n; #将&amp;ltfile&gt;数据指定给纯变量$line(一行一行地)<br>while($line=&lt;FILE&gt;)<br>{<br>print&quot;$line&quot;;<br>}<br>close(file); 就会把abc.txt这个文件的内容显示出来。<br><br>语法2:open(filehandle,&quot;&lt;$filename&quot;)<br>说明:这个语法也可以打开一个存在的文件(read only)。<br>示例:<br>$filesname=&quot;usr/abc.txt&quot;;<br>open(file,&quot;&lt;$filename&quot;)||die&quot;不能打开文件$filename\n&quot;;<br>@array=&amp;ltfile&gt; # 将 &lt;FILE&gt; 全部的数据内容都指定给数组 @array <br>close(file);<br>print &quot;@array&quot;; # 也会把abc.TXT这个文件的内容显示出来。<br><br>语法3:open(filehandle,&quot;&gt;$filename&quot;)<br>说明:建立一个新的文件(write only);如果已经存在这个文件了,就会把旧文件名覆盖掉。并可用print filehandle的方式将数据存入打开的文件中。<br>示例:<br>$filename=&quot;/usr/abc.txt&quot;;<br>open(file,&quot;&gt;$filename&quot;)||die&quot;不能打开文件$filename\n;<br>print file &quot;this is a new line1\n; # \n是换行字符<br>print file &quot;this is a new line2\n;<br>close(file); # 会将数据存在一个新文件中。<br><br>语法4:open(filehandle,&quot;&gt;&gt;$filename&quot;)<br>说明:数据用附加的方式定入一文件(write only),如果指定的文件名不存在的话就会建立一个新的文件。<br>示例:<br>$filename=&quot;/path/abc.txt&quot;;<br>open(file,&quot;&gt;&gt;$filename&quot;)||die&quot;不能打开文件$filename\n&quot;;<br>print file &quot;this is a new line1\n&quot;;<br>print file &quot;this is a new line2\n&quot;;<br>close(file); # 会打数据附加(append)到一个文件(abc.txt)中。<br><br>语法5:open(filehandle,&quot;|unix command&quot;)<br>说明:就会把在filehandle的数据输入给unix的指令来作处理。<br>示例:<br>$mailprog=&quot;/usr/ucb/mail&quot;; # unix系统上的寄信程序(一定要加绝对路径)<br>$who=&quot;mqingyi@126.com&quot;;<br>$open(file,&quot;|$mailprog$who&quot;)||die&quot;打开失败\n&quot;;<br>print file &quot;I love you&#33;\n&quot;;<br>print file &quot;I want to see you.\n&quot;;<br>close(file);<br>该段代码通过 unix 系统的 mail 程序,将 FILE 这个 FILEHANDLE 的数据内容寄给 $who 这个变量所指定的收信人。 <br><br><br>--------------------------------------------------------------------------------<br><br>指令:close<br>用法:close(filehandle)<br>说明:用 open 这个函数来打开一个 filehandle 之后,一定要用 close 批这个函数把所打开的 filehandle 关闭。<br>示例:<br>open(filehandle,&quot;$filename&quot;);<br>close(filehandle);<br><br><br>--------------------------------------------------------------------------------<br><br>指令:pack<br>语法:pack(&quot;指定的格式&quot;,list)<br>说明:pack这个函数会将一个 list 变成所指定的二进制数据格式。在CGI程序分割解码过程中,会用到 pack 这个函数。<br>示例:<br>$string=pack(&quot;c&quot;,65); #这时 $string=&quot;a&quot;; 将65这个ascii码转换成一个unsigned字符,其中c就是指定指转换成 unsigned 字符的意思。 <br><br><br>--------------------------------------------------------------------------------<br><br>指令:read<br>语法:read(filehandle,$string,length) 其中 length 是代表读入字符串的长度(bytes)。<br>说明:用 read 这个函数把 filehandle 中的数据依指定的字符串长度读入之后指派给 $string 这个变量。在cgi程序分割解码过程中,如果 FORM 的传送方式是设定为POST的话,就会将传送的数据设定为标准输入,所以会将数据内容指定给 STDIN 这个标准输入的 filehandle ,而CGI环境变量 $env{&#39;content_length&#39;} 就是代表使用者送出数据内容的长度,因此我们要用 read 这个函数来取得使用者送出的数据内容。<br>示例:<br>read(stdin,$buffer,$env{&#39;content_length&#39;}); # 就会将 stdin 这个标准输入 filehandle 中的数据依指定的字符串长度读入,再指派给 $buffer 这个变量。 <br><br><br>--------------------------------------------------------------------------------<br><br>指令:exit<br>语法:exit<br>说明:退出执行的程序。<br>示例:<br>print&quot;i love cgi\n&quot;; exit; # 表示显示完 &quot;i love cgi&quot; 以后,将退出这个程序。<br><br><br>--------------------------------------------------------------------------------<br><br><br>  <br><br>7.5    文件操作<br>  大多数 Perl 程序都不是孤立的,它们与环境相互作用。很多的程序也需要通过文件操作实现数据的存贮和交换。文件句柄(file handle)是 Perl 程序中为程序和外部世界提供 I/O 连接的名称。建议在 Perl 程序中文件句柄全部使用大写字母,以示与变量等字符串的区别。特别地,可以将 STDIN/STDOUT/STDERR 也认为是 Perl 的文件句柄,分别代表 标准输入/标准输出/标准错误输出。<br><br><br><br>打开及关闭文件<br>      Perl的文件操作与C语言极为相似。如:<br><br>        open(FILENAME,&quot;abc.txt&quot;);<br><br>      该调用为读文件打开,若为写文件而打开,需在文件名前加上大于号:<br><br>        open(FILENAME,&quot;&gt;abc.txt&quot;);<br><br>      若要追加至文件尾,可在文件名前加上两个大于号:<br><br>        open(FILENAME,&quot;&gt;&gt;abc.txt&quot;);<br><br>      以上三种open()格式在成功时返回真,失败时返回假。但程序中通常没有提示,出错时往往会被人们忽略。 通常当需要给出出错提示时,可加入die()函数。例如:<br><br>        open(OUTFILE,&quot;&gt;/tmp/outfile&quot;)|| die &quot;出错,不能建立/tmp/outfile\n&quot;;<br><br>      当 open 操作失败时,就会执行 die 给出出错提示。<br><br>      对文件句柄的操作完成后,可以用 close 操作符关闭文件。如:<br><br>        close(OUTFILE);<br><br><br><br>文件测试<br>      Perl的文件操作也可以先测试文件是否存在,是否可读写等,这样操作起来会更安全。如:<br><br>        $x=&quot;abc.txt&quot;;<br>        if(-e $x) { #abc.txt是否存在?<br>             # 存在操作<br>        } else {<br>             printf &quot;文件不存在。\n&quot;;<br>        }<br><br>    -e 操作符用于测试文件或目录是否存在。<br><br>      以下为所有文件测试操作符的清单:<br><br><br><br>文件测试 测试操作符提供的信息 <br>-r 文件或目录可读 <br>-w 文件或目录可写 <br>-x 文件或目录执行 <br>-o 文件或目录归用户所有 <br>-R 文件或目录对真正用户可读 <br>-W 文件或目录对真正用户可写 <br>-X 文件或目录对真正用户执行 <br>-O 文件或目录归真正用户所有 <br>-e 文件或目录存在 <br>-z 文件存在且大小为0 <br>-s 文件或目录存在且不为0(返回字节数) <br>-f 文件为普通文件 <br>-d 文件为目录 <br>-l 文件为符号链接 <br>-p 文件为命名管道(FIFO) <br>-S 文件为一个套口(socket) <br>-b 文件为块特殊文件 <br>-c 文件为字符特殊文件 <br>-t 打开tty控制台的文件句柄 <br>-u 文件或目录是设置用户ID号 <br>-g 文件或目录是设置用户组ID号 <br>-k 文件或目录的sticky位置位 <br>-T 文件是文本文件 <br>-B 文件是二进制文件 <br>-M 以天为单位的存在时间 <br><br>-A 以天为单位访问时间 <br>-C 以天为单位同代码更改时间 <br>   <br><br>删除文件<br>      Perl的 unlink() 操作符可实现删除文件。如:<br><br>        unlink(&quot;abc.txt&quot;); # 删除abc.txt<br><br><br><br>文件重命名<br>      Perl的rename()操作符可实现文件重命名。如:<br><br>        rename(&quot;abc&quot;,&quot;aka&quot;) || die &quot;出错,不能更名&quot;; <br><br>      此时将文件 abc 更名为 aka,成功返回真,否则给出出错提示。 <br><br><br><br>目录操作<br>      Perl中处理目录非常类似于对文件的处理。<br><br>      打开目录句柄:<br><br>        opendir(ETC,&quot;/etc&quot;)||die &quot;出错,不能打开目录&quot;;<br><br>      关闭目录句柄:<br><br>        closedir(ETC);<br><br>      创建目录:<br><br>        mkdir(&quot;aka&quot;,0777)||die &quot;不能创建 aka 目录&quot;;<br><br>      0777 为文件权限描速数。<br><br>      删除目录:<br><br>        rmdir(&quot;aka&quot;) || die &quot;不能删除 aka 目录&quot;。<br><br>  <br><br>7.6 进程管理<br>  当你向系统 Shell 发送一个命令行时,Shell 创建一个进程来执行这个命令。这个新进程成为 Shell 的子进程,它的执行不依赖于 Shell 但又与 Shell 相互协调。 同样,Perl程序也能启动新进程。<br><br><br><br>使用system()和exec()<br>      生成新进程的最简单的方法就是用 system 操作符。如:<br><br>        system(&quot;date&quot;);<br><br>      若要将输出送至now_day文件,则可以:<br><br>        system(&quot;date&gt;now_day&quot;) || die &quot;不能建立now_day文件&quot;;<br><br><br><br>使用单引号<br>      产生进程的另一方法是将 Shell 命令置于两个单引号之间。如:<br><br>        $nowday=&quot;现在时间:&quot;.&#39;date&#39;<br><br>    $nowday 的值为“现在时间:”和date命令的结果的连接。即:&quot;现在时间:Fri Feb 18 23:49:23 PDT 1998&quot;<br><br><br><br>综合范例<br>      举一个综合例子,要求从date的输入中分析,周未时打印&quot;周未了,轻松一下&quot;,否则打印&quot;努力工作&quot;。简洁的写法为:<br><br>        if(&#39;date&#39;=~/^S/){<br>          printf &quot;周未了,轻松一下\n&quot;;<br>        } else {<br>          printf &quot;努力工作\n&quot;<br>        }<br><br>      date 的输出格式第一个字节为星期,英语中恰好只有周未为 &quot;S&quot; 打头,因此使用了常规表达式判断第一个字符是否为S,即可达到要求。 <br>                       
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站点信息

站点统计| 举报| Archiver| 手机版| 小黑屋

Powered by Discuz! X3.2 © 2001-2014 Comsenz Inc.

GMT+1, 16.11.2024 06:43

关于我们|Apps

() 开元网

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