BASH (1) 简单介绍

  • Post author:
  • Post category:其他



1    BASH 的历史和概貌

BASH 是什么的缩写

Linux 中的其他 Shell

BASH 的主要特点

为什么要学习 BASH 编程呢?因为 BASH 是每个 Linux 发行版都带有的一个标准基础软件,所以学会在 BASH 下编制一些小程序就可以让你对 Linux 系统的管理应付自如;其次 BASH 非常简单,如果不深究 BASH 语法中的细节的话,你可以用 1 个小时就学会他,应该说 BASH 比 HTML 要更容易学;最后即使你不打算用 BASH 编程,但是 Linux 系统中的许多配置文件和脚本都是 BASH 的语法,不懂一点 BASH 的知识就不能很好的理解和使用 Linux 。其实最简单的 BASH 就和 DOS 下的批处理文件类似,只要把要执行的命令一行一行写出来就行。

1.1    BASH 是什么的缩写

BASH = GNU Bourne-Again SHell,BASH 是 GNU 组织开发和推广的一个项目,不过也有一种风趣的说法认为 BASH = Born-Again Shell。

BASH 是 Linux 操作系统上的一个 Shell,是由 /bin/bash 解释执行的。BASH 支持 IEEE POSIX P1003.2/ISO 9945.2 脚本语言工具标准。

1.2    Linux 系统中的其他 Shell

Shell 的概念是从 UNIX 系统中引用过来的,在 Linux 和 UNIX 系统里现在存在这多种不同的 Shell 可以使用。最常用的几种是




Bourne shell (sh)

C shell (csh)

Korn shell (ksh)

三种shell 都有它们的优点和缺点:

Bourne shell 的作者是 Steven Bourne,它是 UNIX 最初使用的 Shell 并且在每种 UNIX 上都可以使用。Bourne Shell 在 Shell 编程方面相当优秀,但在处理与用户的交互方面作得不如其他几种 Shell;

C Shell 由 Bill Joy 所写,它更多的考虑了用户界面的友好性,支持象命令补齐(command-line completion)等一些 Bourne Shell 所不支持的特性,普遍认为C shell 的编程接口做的不如 Bourne Shell,但 C Shell 还是被很多 C 程序员使用,因为 C Shell 的语法和 C 语言很相似,这也是 C Shell 名称的由来;

Korn Shell (ksh) 由 Dave Korn 所写,它集合了 C Shell 和 Bourne Shell 的优点并且和 Bourne Shell 完全兼容。

除了这些 Shell 以外,许多其他的 Shell 程序吸收了这些原来的 Shell 程序的优点而成为新的 Shell 。在 Linux 上常见的有 tcsh (csh 的扩展),Bourne Again shell(bash, sh 的扩展), 和Public Domain Korn shell (pdksh, ksh 的扩展)。

BASH 是大多数 Linux 系统的缺省 Shell。 BASH 只是 Linux 操作系统上的一种 Shell,虽然他是一个比较优秀和主流的 Shell,但是针对不同用户的不同需要和喜好,在 Linux 操作系统上还有几种其他的 Shell,如:ksh、csh、zsh 等。

1.3    BASH 的主要特点



Bourne Again shell (bash), 正如它的名字所暗示的,是 Bourne shell 的扩展


。BASH 与 Bourne shell 完全向后兼容,并且在 Bourne shell 的基础上增加和增强了很多特性。BASH 也包含了很多 csh 和 Korn Shell 里的优点,使得 BASH 有很灵活和强大的编程接口,同时又有很友好的用户界面。为什么要用 BASH 来代替 sh 呢?Bourne Shell 最大的缺点在于它处理用户的输入方面,在 Bourne shell 里键入命令会很麻烦,尤其当你键入很多相似的命令时,而 BASH 准备了几种特性使命令的输入变得更容易。 BASH 的新功能包括 命令补齐、通配符、命令历史记录、别名等。

BASH 是一种解释执行的语言,我们还见过其他一些解释性的语言,如 BASIC 语言、Perl 语言、TCL/TL 等等。解释执行的语言的与编译型语言(如 C 语言)的最大不同就在于运行速度和使用方便程度上。BASH 和后面我们要讲解的 Perl 语言都是解释性语言,他们编写起来很方便,也很快捷,但是由于是解释执行,所以运行速度和效率必将大打折扣。故而今天介绍的 BASH 和 Perl 这两种解释性语言最好的用途就是一些用于完成特定功能的常用的小工具或小程序,对于一些大型的项目、计算复杂的工程或有高级需求的应用还是用 C 语言甚至汇编语言比较好。

下面给出一些 BASH 所不适用的范围:




资源型敏感,对 CPU 负担重的程序

复杂的大项目

需要灵活处理文件的程序,BASH 只能逐行读出文件进行处理

需要图形用户界面的程序

需要直接与系统硬件打交道的程序

需要访问 I/O 端口和网络套接字的程序

需要使用库或和以前的其他代码整合的程序

如果遇到上面这些程序,我们推荐最好用其他编程语言,如:Perl, Tcl, Python 或者直接用 C, C++, Java 。

BASH 中的特殊保留字

保留变量

随机数

运算符

变量的特殊操作

3.1    保留变量

BASH 中有一些保留变量,下面列出了一些:



$IFS  这个变量中保存了用于分割输入参数的分割字符,默认识空格。

$HOME  这个变量中存储了当前用户的根目录路径。

$PATH  这个变量中存储了当前 Shell 的默认路径字符串。

$PS1  表示第一个系统提示符。

$PS2  表示的二个系统提示符。

$PWD  表示当前工作路径。

$EDITOR 表示系统的默认编辑器名称。

$BASH  表示当前 Shell 的路径字符串。

$0, $1, $2, …

表示系统传给脚本程序或脚本程序传给函数的第0个、第一个、第二个等参数。

$#   表示脚本程序的命令参数个数或函数的参数个数。

$$   表示该脚本程序的进程号,常用于生成文件名唯一的临时文件。

$?   表示脚本程序或函数的返回状态值,正常为 0,否则为非零的错误号。

$*   表示所有的脚本参数或函数参数。

$@   和 $* 涵义相似,但是比 $* 更安全。

$!   表示最近一个在后台运行的进程的进程号。

3.2    随机数

随机数是经常要用到的,BASH 中也提供了这个功能,请看下面这个程序:

#!/bin/bash

# Prints different random integer from 1 to 65536



a=$RANDOM



echo $a

exit 0

这个程序可以在每次执行的时候随机的打印出一个大小在 1 到 65536 之间的整数。

3.3    运算符

算术运算符

+ – * / % 表示加减乘除和取余运算

+= -= *= /= 同 C 语言中的含义

位操作符

<< <<= >> >>= 表示位左右移一位操作

& &= | |= 表示按位与、位或操作

~ ! 表示非操作

^ ^= 表示异或操作

关系运算符

< > <= >= == != 表示大于、小于、大于等于、小于等于、等于、不等于操作

&& || 逻辑与、逻辑或操作

3.4    变量的特殊操作

BASH 中还有一些对变量的简洁、快速的操作,大家还记得 “${var}” 和 “$var” 同样是对变量的引用吧,对 ${var} 进行一些变化就可以产生一些新功能:

${var-default} 表示如果变量 $var 还没有设置,则保持 $var 没有设置的状态,并返回后面的默认值 default。

${var=default} 表示如果变量 $var 还没有设置,则取后面的默认值 default。

${var+otherwise} 表示如果变量 $var 已经设置,则返回 otherwise 的值,否则返回空( null )。

${var?err_msg} 表示如果变量 $var 已经设置,则返回该变量的值,否则将后面的 err_msg 输出到标准错误输出上。

请同学们自己尝试下面的例子:

#!/bin/bash

echo ${var?There is an error}

exit 0

还有下面一些用法,这些用法主要用于从文件路径字符串中提取有用信息:

${var#pattern}, ${var##pattern} 用于从变量 $var 中剥去最短(最长)的和 pattern 相匹配的最左侧的串。

${var%pattern}, ${var%%pattern} 用于从变量 $var 中剥去最短(最长)的和 pattern 相匹配的最右侧的串。

另外 BASH 2 中还加入下面一些操作:

${var:pos} 表示去掉变量 $var 中前 pos 个字符。

${var:pos:len} 表示变量 $var 中去掉前 pos 个字符后的剩余字符串的前 len 个字符。

${var/pattern/replacement} 表示将变量 $var 中第一个出现的 pattern 模式替换为 replacement 字符串。

${var//pattern/replacement} 表示将变量 $var 中出现的所有 pattern 模式全部都替换为 replacment 字符串。

BASH 中的其他高级问题

4.1    BASH 中对返回值的处理

无论是在 Shell 中对 BASH 脚本返回值的处理,还是在脚本中对函数返回值的处理,都是通过 “$?” 系统变量来获得。BASH 要求返回值必须为一个整数,不能用 return 语句返回字符串变量。

4.2    用 BASH 设计简单用户界面

BASH 中提供了一个小的语句格式,可以让程序快速的设计出一个字符界面的用户交互选择的菜单,该功能就是由 select 语句来实现的,select 语句的语法为:

select var in [list]

do

statments use $var

done

上面的语法结构在执行后,BASH 会将 [list] 中的所有项加上数字列在屏幕上等待用户选择,在用户作出选择后,变量 $var 中就包含了那个被选中的字符串,然后就可以对该变量进行需要的操作了。我们可以从下面的例子中更直观的来理解这个功能:

#!/bin/bash

OPTIONS=”Hello Quit”

select opt in $OPTIONS; do

if [ “$opt” = “Quit” ]; then

echo done

exit

elif [ “$opt” = “Hello” ]; then

echo Hello World

else

clear

echo bad option

fi

done

exit 0

大家可以试着执行上面的程序,看看是什么执行结果。

4.3    在 BASH 中读取用户输入

BASH 中通过 read 函数来实现读取用户输入的功能,如下面这段程序:

#!/bin/bash

echo Please enter your name

read NAME

echo “Hi! $NAME !”

exit 0

上面这个脚本读取用户的输入,并回显在屏幕上。

另外 BASH 中还提供另外一种称为 here documents 的结构,可以将用户需要通过键盘输入的字符串改为从程序体中直接读入,如密码。下面的小程序演示了这个功能:

#!/bin/bash

passwd=”aka@tsinghua”

ftp -n localhost <<FTPFTP

user anonymous $passwd

binary

bye

FTPFTP

exit 0

这个程序在用户需要通过键盘敲入一些字符时,通过程序内部的动作来模拟键盘输入。请注意 here documents 的基本结构为:

command <<SOMESPECIALSTRING

statments



SOMESPECIALSTRING

这里要求在需要键盘输入的命令后,直接加上 <<符号,然后跟上一个特别的字符串,在该串后按顺序输入本来应该由键盘输入的所有字符,在所有需要输入的字符都结束后,重复一遍前面 <<符号后的“特别的字符串”即表示该输入到此结束。

4.4 一些特殊的惯用法

在 BASH 中 () 一对括号一般被用于求取括号中表达式的值或命令的执行结果,如:(a=hello; echo $a) ,其作用相当于 `…` 。

: 有两个含义,一是表示空语句,有点类似于 C 语言中的单个 “;” 。表示该行是一个空命令,如果被用在 while/until 的头结构中,则表示值 0,会使循环一直进行下去,如下例:

while :

do

operation-1

operation-2



operation-n

done

另外 : 还可以用于求取后面变量的值,比如:

#!/bin/bash

: ${HOSTNAME?} {USER?} {MAIL?}

echo $HOSTNAME

echo $USER

echo $MAIL

exit 0

在 BASH 中 export 命令用于将系统变量输出到外层的 Shell 中了。

4.5 BASH 程序的调试

用 bash -x bash-script 命令,可以查看一个出错的 BASH 脚本到底错在什么地方,可以帮助程序员找出脚本中的错误。

另外用 trap 语句可以在 BASH 脚本出错退出时打印出一些变量的值,以供程序员检查。trap 语句必须作为继 “#!/bin/bash” 后的第一句非注释代码,一般 trap 命令被写作: trap ‘message $checkvar1 $checkvar2’ EXIT 。

4.6 关于 BASH2

使用 bash -version 命令可以看出当前你正在使用的 BASH 是什么版本,一般版本号为1.14或其他版本。而现在机器上一般还安装了一个版本号为 2.0 的 BASH 。该 BASH 也在 /bin 目录下。BASH2 提供了一些新功能,有兴趣的同叙可以自己去看相关资料,或直接 man bash2 即可。