Wei_Steven收集整理1BASH的历史和概貌BASH是什么的缩写Linux中的其他ShellBASH的主要特点为什么要学习BASH编程呢?因为BASH是每个Linux发行版都带有的一个标准基础软件,所以学会在BASH下编制一些小程序就可以让你对Linux系统的管理应付自如;其次BASH非常简单,如果不深究BASH语法中的细节的话,你可以用1个小时就学会他,应该说BASH比HTML要更容易学;最后即使你不打算用BASH编程,但是Linux系统中的许多配置文件和脚本都是BASH的语法,不懂一点BASH的知识就不能很好的理解和使用Linux。其实最简单的BASH就和DOS下的批处理文件类似,只要把要执行的命令一行一行写出来就行。1.1BASH是什么的缩写BASH=GNUBourne-AgainSHell,BASH是GNU组织开发和推广的一个项目,不过也有一种风趣的说法认为BASH=Born-AgainShell。BASH是Linux操作系统上的一个Shell,是由/bin/bash解释执行的。BASH支持IEEEPOSIXP1003.2/ISO9945.2脚本语言工具标准。1.2Linux系统中的其他ShellShell的概念是从UNIX系统中引用过来的,在Linux和UNIX系统里现在存在这多种不同的Shell可以使用。最常用的几种是Bourneshell(sh)Cshell(csh)Kornshell(ksh)三种shell都有它们的优点和缺点:Bourneshell的作者是StevenBourne,它是UNIX最初使用的Shell并且在每种UNIX上都可以使用。BourneShell在Shell编程方面相当优秀,但在处理与用户的交互方面作得不如其他几种Shell;Wei_Steven收集整理CShell由BillJoy所写,它更多的考虑了用户界面的友好性,支持象命令补齐(command-linecompletion)等一些BourneShell所不支持的特性,普遍认为Cshell的编程接口做的不如BourneShell,但CShell还是被很多C程序员使用,因为CShell的语法和C语言很相似,这也是CShell名称的由来;KornShell(ksh)由DaveKorn所写,它集合了CShell和BourneShell的优点并且和BourneShell完全兼容。除了这些Shell以外,许多其他的Shell程序吸收了这些原来的Shell程序的优点而成为新的Shell。在Linux上常见的有tcsh(csh的扩展),BourneAgainshell(bash,sh的扩展),和PublicDomainKornshell(pdksh,ksh的扩展)。BASH是大多数Linux系统的缺省Shell。BASH只是Linux操作系统上的一种Shell,虽然他是一个比较优秀和主流的Shell,但是针对不同用户的不同需要和喜好,在Linux操作系统上还有几种其他的Shell,如:ksh、csh、zsh等。1.3BASH的主要特点BourneAgainshell(bash),正如它的名字所暗示的,是Bourneshell的扩展。BASH与Bourneshell完全向后兼容,并且在Bourneshell的基础上增加和增强了很多特性。BASH也包含了很多csh和KornShell里的优点,使得BASH有很灵活和强大的编程接口,同时又有很友好的用户界面。为什么要用BASH来代替sh呢?BourneShell最大的缺点在于它处理用户的输入方面,在Bourneshell里键入命令会很麻烦,尤其当你键入很多相似的命令时,而BASH准备了几种特性使命令的输入变得更容易。BASH的新功能包括命令补齐、通配符、命令历史记录、别名等。BASH是一种解释执行的语言,我们还见过其他一些解释性的语言,如BASIC语言、Perl语言、TCL/TL等等。解释执行的语言的与编译型语言(如C语言)的最大不同就在于运行速度和使用方便程度上。BASH和后面我们要讲解的Perl语言都是解释性语言,他们编写起来很方便,也很快捷,但是由于是解释执行,所以运行速度和效率必将大打折扣。故而今天介绍的BASH和Perl这两种解释性语言最好的用途就是一些用于完成特定功能的常用的小工具或小程序,对于一些大型的项目、计算复杂的工程或有高级需求的应用还是用C语言甚至汇编语言比较好。下面给出一些BASH所不适用的范围:资源型敏感,对CPU负担重的程序复杂的大项目需要灵活处理文件的程序,BASH只能逐行读出文件进行处理需要图形用户界面的程序Wei_Steven收集整理需要直接与系统硬件打交道的程序需要访问I/O端口和网络套接字的程序需要使用库或和以前的其他代码整合的程序如果遇到上面这些程序,我们推荐最好用其他编程语言,如:Perl,Tcl,Python或者直接用C,C++,Java。2BASH的基本语法最简单的例子——HelloWorld!关于输入、输出和错误输出BASH中对变量的规定(与C语言的异同)BASH中的基本流程控制语法函数的使用2.1最简单的例子——HelloWorld!几乎所有的讲解编程的书给读者的第一个例子都是HelloWorld程序,那么我们今天也就从这个例子出发,来逐步了解BASH。用vi编辑器编辑一个hello文件如下:#!/bin/bash#ThisisaverysimpleexampleechoHelloWorld这样最简单的一个BASH程序就编写完了。这里有几个问题需要说明一下:一,第一行的#!是什么意思二,第一行的/bin/bash又是什么意思三,第二行是注释吗四,echo语句五,如何执行该程序#!是说明hello这个文件的类型的,有点类似于Windows系统下用不同文件后缀来表示不同文件类型的意思(但不相同)。Linux系统根据#!及该字串后面的信息确定该文件的类型,关于这一问题同学们回去以后可以通过manmagic命令及/usr/share/magic文件来了解这方面的更多内容。在BASH中第一行的#!及后面的/bin/bash就表明该文件是一个BASH程序,需要由/bin目录下的bash程序来解释执行。BASH这个程序一般是存放在/bin目录下,如果你的Linux系统比较特别,bash也有可能被存放在/sbin、/usr/local/bin、/usr/bin、/usr/sbin或/usr/local/sbin这样的目录下;如果还找不到,你可以用locatebashfind/-namebash2/dev/null或Wei_Steven收集整理whereisbash这三个命令找出bash所在的位置;如果仍然找不到,那你可能需要自己动手安装一个BASH软件包了。第二行的#Thisisa...就是BASH程序的注释,在BASH程序中从“#”号(注意:后面紧接着是“!”号的除外)开始到行尾的多有部分均被看作是程序的注释。的三行的echo语句的功能是把echo后面的字符串输出到标准输出中去。由于echo后跟的是HelloWorld这个字符串,因此HelloWorld这个字串就被显示在控制台终端的屏幕上了。需要注意的是BASH中的绝大多数语句结尾处都没有分号。如何执行该程序呢?有两种方法:一种是显式制定BASH去执行:$bashhello或$shhello(这里sh是指向bash的一个链接,“lrwxrwxrwx1rootroot4Aug2005:41/bin/sh-bash”)或者可以先将hello文件改为可以执行的文件,然后直接运行它,此时由于hello文件第一行的#!/bin/bash的作用,系统会自动用/bin/bash程序去解释执行hello文件的:$chmodu+xhello$./hello此处没有直接“$hello”是因为当前目录不是当前用户可执行文件的默认目录,而将当前目录“.”设为默认目录是一个不安全的设置。需要注意的是,BASH程序被执行后,实际上Linux系统是另外开设了一个进程来运行的。2.2关于输入、输出和错误输出在字符终端环境中,标准输入/标准输出的概念很好理解。输入即指对一个应用程序或命令的输入,无论是从键盘输入还是从别的文件输入;输出即指应用程序或命令产生的一些信息;Linux系统下还有一个标准错误输出的概念,这个概念主要是为程序调试和系统维护目的而设置的,错误输出于标准输出分开可以让一些高级的错误信息不干扰正常的输出信息,从而方便一般用户的使用。在Linux系统中:标准输入(stdin)默认为键盘输入;标准输出(stdout)默认为屏幕输出;标准错误输出(stderr)默认也是输出到屏幕(上面的std表示standard)。在BASH中使用这些概念时一般将标准输出表示为1,将标准错误输出表示为2。下面我们举例来说明如何使用他们,特别是标准输出和标准错误输出。Wei_Steven收集整理输入、输出及标准错误输出主要用于I/O的重定向,就是说需要改变他们的默认设置。先看这个例子:$lsls_result$ls-lls_result上面这两个命令分别将ls命令的结果输出重定向到ls_result文件中和追加到ls_result文件中,而不是输出到屏幕上。就是输出(标准输出和标准错误输出)重定向的代表符号,连续两个符号,即则表示不清除原来的而追加输出。下面再来看一个稍微复杂的例子:$find/home-namelost*2err_result这个命令在符号之前多了一个2,2表示将标准错误输出重定向。由于/home目录下有些目录由于权限限制不能访问,因此会产生一些标准错误输出被存放在err_result文件中。大家可以设想一下find/home-namelost*2err_result命令会产生什么结果?如果直接执行find/home-namelost*all_result,其结果是只有标准输出被存入all_result文件中,要想让标准错误输出和标准输入一样都被存入到文件中,那该怎么办呢?看下面这个例子:$find/home-namelost*all_result2&1上面这个例子中将首先将标准错误输出也重定向到标准输出中,再将标准输出重定向到all_result这个文件中。这样我们就可以将所有的输出都存储到文件中了。为实现上述功能,还有一种简便的写法如下:$find/home-namelost*&all_result如果那些出错信息并不重要,下面这个命令可以让你避开众多无用出错信息的干扰:$find/home-namelost*2/dev/null同学们回去后还可以再试验一下如下几种重定向方式,看看会出什么结果,为什么?$find/home-namelost*all_result1&2$find/home-namelost*2all_result1&2$find/home-namelost*2&1all_result另外一个非常有用的重定向操作符是-,请看下面这个例子:Wei_Steven收集整理$(cd/source/directory&&tarcf-.)|(cd/dest/directory&&tarxvfp-)该命令表示把/source/directory目录下的所有文件通过压缩和解压,快速的全部移动到/dest/directory目录下去,这个命令在/source/directory和/dest/directory不处在同一个文件系统下时将显示出特别的优势。下面还几种不常见的用法:n&-表示将n号输入关闭&-表示关闭标准输入(键盘)n&-表示将n号输出关闭&-表示将标准输出关闭2.3BASH中对变量的规定(与C语言的异同)好了下面我们进入正题,先看看BASH中的变量是如何定义和使用的。对于熟悉C语言的程序员,我们将解释BASH中的定义和用法与C语言中有何不同。2.3.1.BASH中的变量介绍我们先来从整体上把握一下BASH中变量的用法,然后再去分析BAS