Shell基础知识

Posted on 2013-12-27 16:55  相识,非偶然  阅读(210)  评论(0)    收藏  举报


  Shell 简介

Shell 是 系统 的 用户界面 ,提供了用户与 内核 进行交互操作的一种 接口 。它接收用户输入的命令并把它送入内核去执行。 

实际上 Shell 是一个命令解释器,它解释由用户输入的命令并且把它们送到内核。不仅如此, Shell 有自己的编程语言用于对命令的编辑,它允许用户编写由 shell 命令组成的程序。 Shell 编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的 Shell 程序与其他应用程序具有同样的效果。 

Linux 提供了像 Microsoft   Windows 那样的可视的命令输入界面 -- X Window 的 图形用户界面 ( GUI )。它提供了很多窗口管理器,其操作就象 Windows 一样,有窗口、图标和菜单,所有的管理都是通过鼠标控制。现在比较流行的窗口管理器是 KDE 和 GNOME 。 

每个 Linux 系统的用户可以拥有他自己的用户界面或 Shell ,用以满足他们自己专门的 Shell 需要。 

同 Linux 本身一样, Shell 也有多种不同的版本。目前主要有下列版本的 Shell : 

Bourne Shell :是 贝尔实验室 开发的。 

BASH :是 GNU 的 Bourne Again Shell ,是 GNU 操作系统上默认的 shell 。 

Korn Shell :是对 Bourne S h ell 的发展,在大部分内容上与 Bourne Shell 兼容。 

C Shell :是 SUN 公司 Shell 的 BSD 版本。

其实作为命令语言互动式地解释和执行用户输入的命令只是 Shell 功能的一个方面, Shell 还可以用来进行程序设计,它提供了定义变量和参数的手段以及丰富的程序控制结构。使用 Shell 编程类似于 DOS 中的批处理文件,称为 Shell script ,又叫 Shell 程序或 Shell 命令文件。 

Shell 基本语法

像高级程序设计语言一样, Shell 也提供说明和使用变量的功能。对 Shell 来讲,所有变量的取值都是一个字串, Shell 程序采用 $var 的形式来引用名为 var 的变量的值。

Shell 有以下几种基本类型的变量。 ( 1 ) Shell 定义的环境变量:

Shell 在开始执行时就已经定义了一些和系统的工作环境有关的变量,用户还可以重新定义这些变量,常用的 Shell 环境变量有:

HOME  用于保存注册目录的完全路径名。

PATH  用于保存用冒号分隔的目录路径名, Shell 将按 PATH 变量中给出的顺序搜索这些目录,找到的第一个与命令名称一致的可执行文件将被执行。

TERM  终端的类型。

UID  当前用户的识别字,取值是由数位构成的字串。

PWD  当前工作目录的绝对路径名,该变量的取值随 cd 命令的使用而变化。 ( 2 )用户定义的变量:

用户可以按照下面的语法规则定义自己的变量:

变量名   =   变量值

要注意的一点是,在定义变量时,变量名前不应加符号 $ ,在引用变量的内容时则应在变量名前加 $ ;在给变量赋值时,等号两边一定不能留空格,若变量中本身就包含了空格,则整个字串都要用双引号括起来。

在编写 Shell 程序时,为了使变量名和命令名相区别,建议所有的变量名都用大写字母来表示。

有时我们想要在说明一个变量并对它设置为一个特定值后就不在改变它的值时,可以用下面的命令来保证一个变量的只读性:

readonly  变量名

export ,输出当前各环境变量的值 。 在任何时候,创建的变量都只是当前 Shell 的局部变量,所以不能被 Shell 运行的其他命令或 Shell 程序所利用,而 export 命令可以将一个局部变量提供给 Shell 执行的其他命令使用,其格式为:

export  变量名

也可以在给变量赋值的同时使用 export 命令:

export  变量名 = 变量值

使用 export 说明的变量,在 Shell 以后运行的所有命令或程序中都可以访问到。 ( 3 ) 位置参数:

位置参数是一种在调用 Shell 程序的命令行中按照各自的位置决定的变量,是在程序名之后输入的参数。位置参数之间用空格分隔, Shell 取第一个位置参数替换程序文件中的 $1 ,第二个替换 $2 ,依次类推。 $0 是一个特殊的变量,它的内容是当前这个 Shell 程序的文件名,所以, $0 不是一个位置参数,在显示当前所有的位置参数时是不包括 $0 的。 ( 4 ) 预定义变量:

预定义变量和环境变量相类似,也是在 Shell 一开始时就定义了的变量。所不同的是,用户只能根据 Shell 的定义来使用这些变量,而不能重定义它。所有预定义变量都是由 $ 符和另一个符号组成的,常用的 Shell 预定义变量有:

$#  位置参数的数量。

$*  所有位置参数的内容。

$?  命令执行后返回的状态。

$$  当前进程的进程号。

$!  后台运行的最后一个进程号。

$0  当前执行的进程名。

其中, $? 用于检查上一个命令执行是否正确。(在 Linux 中,命令退出状态为 0 表示该命令正确执行,任何非 0 值表示命令出错。)

$$ 变量最常见的用途是用做暂存文件的名字以保证暂存文件不会重复。

3 ) 局部变量
local VAR=VALUE

5 ) 参数置换的变量:

Shell 提供了参数置换功能以便用户可以根据不同的条件来给变量赋不同的值。参数置换的变量有 4 种,这些变量通常与某一个位置参数相联系,根据指定的位置参数是否已经设置类决定变量的取值,它们的语法和功能分别如下。

a.  变量 =${ 参数 -word} :如果设置了参数,则用参数的值置换变量的值,否则用 word 置换。即这种变量的值等于某一个参数的值,如果该参数没有设置,则变量就等于 word 的值。

b.  变量 =${ 参数 =word} :如果设置了参数,则用参数的值置换变量的值,否则把变量设置成 word ,然后再用 word 替换参数的值。注意,位置参数不能用于这种方式,因为在 Shell 程序中不能为位置参数赋值。

c.  变量 =${ 参数? word} :如果设置了参数,则用参数的值置换变量的值,否则就显示 word 并从 Shell 中退出,如果省略了 word ,则显示标准信息。这种变量要求一定等于某一个参数的值。如果该参数没有设置,就显示一个信息,然后退出,因此这种方式常用于出错指示。

d.  变量 =${ 参数 +word} :如果设置了参数,则用 word 置换变量,否则不进行置换。

所有这 4 种形式中的 “ 参数 ” 既可以是位置参数,也可以是另一个变量,只是用位置参数的情况比较多。

e.  变量 =${parameter:offset:length} :取子串,从 offset 处的后一个字符开始,取 lenth 长的子串



Shell 程序设计的流程控制

和其他高级程序设计语言一样, Shell 提供了用来控制程序执行流程的命令,包括条件分支和循环结构,用户可以用这些命令创建非常复杂的程序。

与传统语言不同的是, Shell 用于指定条件值的不是布尔运算式,而是命令和字串。 1 .测试命令

test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件 3 个方面的测试,其测试符和相应的功能分别如下。

1 )数值测试:

-eq  等于则为真。

-ne  不等于则为真。

-gt  大于则为真。

-ge  大于等于则为真。

-lt  小于则为真。

-le  小于等于则为真。

2 )字串测试:

=  等于则为真。

!=  不相等则为真。

-z 字串 字串长度伪则为真。

-n 字串 字串长度不伪则为真。

3 )文件测试:

-e 文件名 如果文件存在则为真。

-r 文件名 如果文件存在且可读则为真。

-w 文件名 如果文件存在且可写则为真。

-x 文件名 如果文件存在且可执行则为真。

-s 文件名 如果文件存在且至少有一个字符则为真。

-d 文件名 如果文件存在且为目录则为真。

-f 文件名 如果文件存在且为普通文件则为真。

-c 文件名 如果文件存在且为字符型特殊文件则为真。

-b 文件名 如果文件存在且为块特殊文件则为真。

另外, Linux 还提供了与(!)、或( -o )、非( -a )三个逻辑操作符,用于将测试条件连接起来,其优先顺序为:!最高, -a 次之, -o 最低。

同时, bash 也能完成简单的算术运算,格式如下:

$[expression]

例如 :

var1=2

var2=$[var1*10+1]

则 var2 的值为 212if 条件语句 

Shell 程序中的条件分支是通过 if 条件语句来实现的,其一般格式为:

if  条件命令串

then

条件为真时的命令串

else

条件为假时的命令串

fi 3for 循环

for 循环对一个变量的可能的值都执行一个命令序列。赋给变量的几个数值既可以在程序内以数值列表的形式提供,也可以在程序以外以位置参数的形式提供。 for 循环的一般格式为:

for 变量名    [in 数值列表 ]

do

若干个命令行

done

变量名可以是用户选择的任何字串,如果变量名是 var ,则在 in 之后给出的数值将顺序替换循环命令列表中的 $var 。如果省略了 in ,则变量 var 的取值将是位置参数。对变量的每一个可能的赋值都将执行 dodone 之间的命令列表。 4while 和 until 循环

while 和 until 命令都是用命令的返回状态值来控制循环的。 While 循环的一般格式为:

while

若干个命令行 1

do

若干个命令行 2

done

只要 while 的 “ 若干个命令行 1” 中最后一个命令的返回状态为真, while 循环就继续执行 do...done 之间的 “ 若干个命令行 2” 。

until 命令是另一种循环结构,它和 while 命令相似,其格式如下:

until

若干个命令行 1

do

若干个命令行 2

done

until 循环和 while 循环的区别在于: while 循环在条件为真时继续执行循环,而 until 则是在条件为假时继续执行循环。

Shell 还提供了 true 和 false 两条命令用于创建无限循环结构,它们的返回状态分别是总为 0 或总为非 05case 条件选择

if 条件语句用于在两个选项中选定一项,而 case 条件选择为用户提供了根据字串或变量的值从多个选项中选择一项的方法,其格式如下:

case string in

exp-1)

若干个命令行 1

;;

exp-2)

若干个命令行 2

;;

……

*)

其他命令行

esac

Shell 通过计算字串 string 的值,将其结果依次和运算式 exp-1, exp-2 等进行比较,直到找到一个匹配的运算式为止。如果找到了匹配项,则执行它下面的命令直到遇到一对分号 ( ;; ) 为止。

case 运算式中也可以使用 Shell 的通配符( “*” 、 “ ? ” 、 “[ ]” )。通常用  *  作为 case 命令的最后运算式以便在前面找不到任何相应的匹配项时执行 “ 其他命令行 ” 的命令。 6 .无条件控制语句 breakcontinue

break 用于立即终止当前循环的执行,而 contiune 用于不执行循环中后面的语句而立即开始下一个循环的执行。这两个语句只有放在 dodone 之间才有效。 7 .函数定义

在 Shell 中还可以定义函数。函数实际上也是由若干条 Shell 命令组成的,因此它与 Shell 程序形式上是相似的,不同的是它不是一个单独的进程,而是 Shell 程序的一部分。函数定义的基本格式为:

functionname

{

若干命令行

}

调用函数的格式为:

functionname param1 param2…

Shell 函数可以完成某些例行的工作,而且还可以有自己的退出状态,因此函数也可以作为 if, while 等控制结构的条件。

在函数定义时不用带参数说明,但在调用函数时可以带有参数,此时 Shell 将把这些参数分别赋予相应的位置参数 $1, $2, ... 及 $*8 .命令分组

在 Shell 中有两种命令分组的方法: () 和 {} 。前者当 Shell 执行 () 中的命令时将再创建一个新的子进程,然后这个子进程去执行圆括弧中的命令。当用户在执行某个命令时不想让命令运行时对状态集合(如位置参数、环境变量、当前工作目录等)的改变影响到下面语句的执行时,就应该把这些命令放在圆括弧中,这样就能保证所有的改变只对子进程产生影响,而父进程不受任何干扰。 {} 用于将顺序执行的命令的输出结果用于另一个命令的输入(管道方式)。当我们要真正使用圆括弧和花括弧时(如计算运算式的优先顺序),则需要在其前面加上转义符( \ )以便让 Shell 知道它们不是用于命令执行的控制所用。



运行 Shell 程序的方法 

用户可以用任何编辑程序来编写 Shell 程序。因为 Shell 程序是解释执行的,所以不需要编译成目的程序。按照 Shell 编程的惯例,以 bash 为例,程序的第一行一般为 “# ! /bin/bash” ,其中  #  表示该行是注释,叹号 ! 告诉 Shell 运行叹号之后的命令并用文档的其余部分作为输入,也就是运行 /bin/bash 并让 /bin/bash 去执行 Shell 程序的内容。

执行 Shell 程序的方法有 3 种。 1 . sh Shell 程序文件名

这种方法的命令格式为:

bash Shell 程序文件名

这实际上是调用一个新的 bash 命令解释程序,而把 Shell 程序文件名作为参数传递给它。新启动的 Shell 将去读指定的文件,可执行文件中列出的命令,当所有的命令都执行完后结束。该方法的优点是可以利用 Shell 调试功能。 2 . sh

格式为:

bash< Shell 程序名

这种方式就是利用输入重定向,使 Shell 命令解释程序的输入取自指定的程序文件。 3 .用 chmod 命令使 Shell 程序成为可执行的

一个文件能否运行取决于该文档的内容本身可执行且该文件具有执行权。对于 Shell 程序,当用编辑器生成一个文件时,系统赋予的许可权都是 644(rw-r-r--) ,因此,当用户需要运行这个文件时,只需要直接键入文件名即可。

在这 3 种运行 Shell 程序的方法中,最好按下面的方式选择:当刚创建一个 Shell 程序,对它的正确性还没有把握时,应当使用第一种方式进行调试。当一个 Shell 程序已经调试好时,应使用第三种方式把它固定下来,以后只要键入相应的文件名即可,并可被另一个程序所调用。 4 . bash 程序的调试

在编程过程中难免会出错,有的时候,调试程序比编写程序花费的时间还要多, Shell 程序同样如此。

Shell 程序的调试主要是利用 bash 命令解释程序的选择项。调用 bash 的形式是:

bash - 选择项 Shell 程序文件名

几个常用的选择项是:

-e  如果一个命令失败就立即退出。

-n  读入命令但是不执行它们。

-u  置换时把未设置的变量看做出错。

-v  当读入 Shell 输入行时把它们显示出来。

-x  执行命令时把命令和它们的参数显示出来。

上面的所有选项也可以在 Shell 程序内部用 “set - 选择项 ” 的形式引用,而 “set + 选择项 ” 则将禁止该选择项起作用。如果只想对程序的某一部分使用某些选择项时,则可以将该部分用上面两个语句包围起来。

1 )未置变量退出和立即退出

未置变量退出特性允许用户对所有变量进行检查,如果引用了一个未赋值的变量就终止 Shell 程序的执行。 Shell 通常允许未置变量的使用,在这种情况下,变量的值为空。如果设置了未置变量退出选择项,则一旦使用了未置变量就显示错误信息,并终止程序的运行。未置变量退出选择项为 -u 。

当 Shell 运行时,若遇到不存在或不可执行的命令、重定向失败或命令非正常结束等情况时,如果未经重新定向,该出错信息会显示在终端屏幕上,而 Shell 程序仍将继续执行。要想在错误发生时迫使 Shell 程序立即结束,可以使用 -e 选项将 Shell 程序的执行立即终止。

2 ) Shell 程序的跟踪

调试 Shell 程序的主要方法是利用 Shell 命令解释程序的 -v 或 -x 选项来跟踪程序的执行。 -v 选择项使 Shell 在执行程序的过程中,把它读入的每一个命令行都显示出来,而 -x 选择项使 Shell 在执行程序的过程中把它执行的每一个命令在行首用一个 + 加上命令名显示出来。并把每一个变量和该变量所取的值也显示出来。因此,它们的主要区别在于:在执行命令行之前无 -v ,则显示出命令行的原始内容,而有 -v 时则显示出经过替换后的命令行的内容。

除了使用 Shell 的 -v 和 -x 选择项以外,还可以在 Shell 程序内部采取一些辅助调试的措施。例如,可以在 Shell 程序的一些关键地方使用 echo 命令把必要的信息显示出来,它的作用相当于 C 语言中的 printf 语句,这样就可以知道程序运行到什么地方及程序目前的状态。  





eexec halt -p

取得变量的字符长度: ${#VARNAME}

取得终端的宽度:

stty -F /dev/pts/0 size|awk '{print $2}'  

脚本中,实现信号捕捉,但 915 无法捕捉

信号:

kill -SIGNAL PID

1:HUP

2;INT

9:KILL

15:TERM

Ctrl+c : SIGINT

trap 命令:

trap  ‘ COMMAND1 [; COMMAND2] ’  信号列表

执行多个名句,用;号隔开