常用 Shell<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

1.     Shelll 种类

Linux 中的 Shelll 有多种类型,其中最常见的是 Bourne Shelll sh )、 C Shelll csh )和 Korn Shelll ksh )。三种 Shelll 各有优点。 Bourne Shelll UNIX 最初的 Shelll ,并且在没种 UNIX 上都可以用。 Bourne Shelll Shelll 编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种 Shelll Bash Bourne Again Shelll )是 Bourne Shelll 的扩展,与 Bouren Shelll 完全向下兼容,并且增加了许多特性。它还包含了很多 C Shelll Korn Shelll 中的优点,有灵活和强大的编程接口,同时又有很友好的用户界面。

2Bash

Bash 是大多数 Linux 系统(包括红旗 Linux 系统)的默认 Shelll Bash 有以下优点:

(1) 补全命令。在 Bash 命令提示符下输入命令或程序名时,若没有输全命令或程序名,按“ Tab ”键, Bash 将自动补全命令或程序名

(2) 通配符。在 Bash 下可以使用通配符“ * ”和 “?”. “*” 可以替代多个字符,而“?“则替代一个字符

(3) 历史命令。在 Bash 下可以自动跟踪用户每次输入的命令,并把输入的命令保存在历史类表缓冲区中

(4) 别名。在 Bash 下,可用 alias unalias 命令给命令或可执行程序起别名和删除别名,这样可以以自己习惯方式输入命令。

(5) 输入、输出重定向。输入重定向用于改变命令的输入,输出重定向用于改变命令的输出。输出重定向更为常用,它经常用于将命令的结果输入到文件中,而不是屏幕上。输入重定向的命令时“ < “,输出重定向的命令时 ”>” 。输入输出重定向的功能和用法与 DOS/Windows 系统完全相同。

[root@localhost ~]# wc</etc/passwd

// 输入重定向

[root@localhost ~]# ls

// 显示文件

[root@localhost ~]# ls >dir.out

// 输出重定向

[root@localhost ~]# ls >> dir1.out

// >> “表示要将一条命令的输出结果追加到文件” dir1.out “的后面,该文件的原有内容不被破坏,如果使用” > “,则文件原有内容被覆盖。

(1) 管道。管道用于将以系列的命令连接起来,也就是把前面命令的输出作为后面命令的输入。管道的命令是“ | ”。管道的功能和用法与 DOS/Windows 系统的完全相同。

$cat dir.out|grep “test”|wc –l

管道将 cat 命令(列出一个文件的内容)的输出送给 grep 命令, grep 命令在输入了查找单词 test,grep 的输出则是所有包含的单词 test 的行,这个输出又被送给 wc 命令, wc 命令统计出输入中的行数。假设文件“ dir.out ”的内容如下:

[root@localhost ~]# echo "This is a test">> dir.out

[root@localhost ~]# echo "Today is Monday">> dir.out

[root@localhost ~]# echo "We should have a test">>dir.out

[root@localhost ~]# cat dir.out

This is a test

Today is Monday

We should have a test

[root@localhost ~]# cat dir.out|grep "test"|wc -l

2

[root@localhost ~]#

特殊变量

Shelll 中有一些变量是由系统设置好的,用户不能重新设置

(1)$# 表示命令行上的个数

(2)$? 表示上一条命令执行后的返回值

(3)$$ 表示当前进程的进程号

(4)#! 表示上一个后台命令对应的进程号

(5)$* 表示命令行上的所有参数串

(6)$@ $* 的含义相同

[root@localhost ~]# vim a

// 创建一个 a 脚本文件

[root@localhost ~]# chmod a+x a

// 给脚本 a 执行权限

[root@localhost ~]# ./a My Name is Chen Boqiang

// 执行脚本 a 在后面输入参数

All argument list:My Name is Chen Boqiang

// 显示输入的参数

The total number of argument is:5

// 显示参数个数

[root@localhost ~]# cat -n a

// 显示 a 脚本的内容

     1  #!/bin/bash

// 脚本的注释说明

     2  echo "All argument list:$@"

// 存储所有命令行输入的参数

     3  echo "The total number of argument is:$#"

// 程序中命令行参数的个数

     4  #end

[root@localhost ~]#

[root@localhost ~]# dir=/usr/local/arm

//Shelll 变量分两类:环境变量和临时变量。环境变量是永久性变量,其值不会随 Shelll 脚本执行结束而消失。而临时变量是在 Shelll 程序内部定义的,其使用范围仅限于定义它的程序,离开了本程序就不能在用它,而且当程序执行完毕,它的值也就不存在了。这里属于临时变量。变量名是以字母或下划线打头的字母、数字和下划线序列,并且区分大小写字母。变量赋值:变量名 = 字符串

[root@localhost ~]# echo $dir

//echo 用来显示变量值

/usr/local/arm

[root@localhost ~]# echo dir

//echo $dir 执行时,将变量 dir 的值显示出来;而执行命令 echo dir 时,因为 dir 的前没有符号 ”$” ,认为不是变量,而是一般的字符串常量。

dir

[root@localhost ~]# today=Sunday

// 变量名 = 字符串

[root@localhost ~]# echo $today $Today

// 显示变量值,其实变量 today Today 是不同的变量,前者被显示赋值,而后者未被赋值。所以,在执行 echo 命令时,把 today 的值“ Sunday ”显示出来,而 Today 值等于空串。

Sunday

[root@localhost ~]# str="Happy New Year!"

// 变量名 = 字符串 ,加!时执行不了的

bash: !": event not found

[root@localhost ~]# str="Happy New Year"

// 赋值,变量名 = 字符串,如果在赋给变量的值中要含有空格、制表符或换行符,那么,就应该用双引号把这个字符串括起来。

[root@localhost ~]# echo "Wish You $str"

// 显示字符串和变量值

Wish You Happy New Year

[root@localhost ~]# read name

// 输入 read 命令,加变量

Chen Boqiang

// 输入 name 的值

[root@localhost ~]# echo "My Name is $name"

// 显示输出的结果

My Name is Chen Boqiang

[root@localhost ~]# read a b c

//read 命令有个参数

51cto www com

// 输入三个字符串,中间以空格隔开

[root@localhost ~]# echo http://$b.$a.$c

显示输出结果

http://www.51cto.com

[root@localhost ~]#

Shelll 中的特殊字符

通配符

通常的通配符有三种:

* 星号 , 它匹配任意字符的 0 次或多次出现。但注意,文件名前面的圆点( . )和路径名中的斜线( / )必须显示匹配。

?问号,它匹配任意一个字符

[] 一对方括号,其中有一个字符组。其作用是匹配该字符组所限定的任意一个字符。应该注意:字符 * 和?在一对方括号外面是通配符,若出现在其内部,它们就失去通配符的能力了。

!叹号,若它紧跟在一对方括号的左方括号 [ 之后,则表示不在一对方括号中所列出的字符。

引号

Shell 中引号分为三种 : 单引号、双引号、和倒引号

双引号

由双引号括起来的字符,除 $ 、倒引号和反斜线( \ )仍保留其功能外,其余字符通常作为普通字符对待。

 

[root@localhost ~]# vim ex8

// 创建一个执行文件,命名为 ex8

[root@localhost ~]# sh ex8

// 执行 ex8 文件

current directory is /root

// 显示当前路径

home directory is /root

file *.?

directory '/root'

[root@localhost ~]# cat -n ex8

     1  echo "current directory is `pwd`"

// 命令替换有两种形式的命令替换:一种是使用倒引号引用命令,其一般形式是 ` 命令表 `

     2  echo "home directory is $HOME"

     3  echo "file *.?"

     4  echo "directory '$HOME'"

// 用单引号引用命令

[root@localhost ~]#

条件测试

test 命令进行条件测试。格式为:

Test expression

[expression]

例如:

[root@localhost ~]# test 8 = 9

// 测试字符串 8 是否等于 9

[root@localhost ~]# echo $?

//$? 表示上一条命令执行后的返回值

1

// 其值为假,返回 1

[root@localhost ~]# [ 8 = 8 ]

// 省略 ” test” ,改用中括号形式,注意中括号中的空格

[root@localhost ~]# echo $?

//$? 表示上一条命令执行后的返回值

0

// 返回值为真

[root@localhost ~]# [ 8 = 9 ]

// 省略“ test ”,改用中括号,作用完全一样

[root@localhost ~]# echo $?

//$? 表示上一条命令执行后的返回值

1

[root@localhost ~]#

Test 命令可以和多种系统运算符一起使用。这些运算符可以分为 4 类:整理运算符、字符串运算符、文件运算符和逻辑运算符

(1) 数值运算符:用来判断数值表达式的真假。可用的运算符如下:

int1 –eq int2  如果 int1 = int2 ,则为真 .

int1 –ge int2  如果 int1>=int2, 则为真

int1 –gt int2  如果 int1> int2 ,则为真

int1 –le int2  如果 int1<=int2 ,则为真

int1-lt int2   如果 int1< int2, 则为真

int1 –ne int2 如果 int!=int2 ,则为真

(2) 字符串运算符,用来判断字符串表达式的真假,可用的运算符如下:

str1 = str2  如果 str1 str2 相同,则为真

str1!=str2  如果 str1 str2 不相同,则为真

str        如果 str 不为空 ,则为真

-n str       如果 str 的长度大于零,则为真

-z str      如果 str 的长度等于零,则为真

3 )文件运算符:用来判断文件是否存在、类型及属性。可用的运算符如下:

-d filename     如果 filename 为目录,则为真

-f filename      如果 filename 为普通的文件,则为真

-r filename      如果 filename 为只读,则为真

-s filename     如果 filename 的长度大于零,则为零

-w filename    如果 filename 为可写,则为真

-x filename     如果 filename 为可执行,则为真

4 )逻辑运算符:用来结合表达式或取的表达式相反值。可用的运算符如下:

expr                       如果 expr 为假,则返回真

expr1 –a expr2         如果 expr1 expr2 同时为真,则返回真

expr1 –o expr2         如果 expr1 expr2 有一个为真,则返回真

 

[root@localhost ~]# [ -d /etc ]

// 判断 /etc 是否为目录

[root@localhost ~]# echo $?

// 显示其返回值

0

// 其值为真,返回 0

[root@localhost ~]# [ -w /etc ]

// 判断用户对目录 /etc 是否有写的权限

[root@localhost ~]# echo $?

// 超级用户 root 返回值为真,如果是普通用户为假

0

[root@localhost ~]# [ -f install.log -a -w install.log ]

// 判断 install.log 是否存在且具有可写的权限

[root@localhost ~]# echo $?

// 显示为真

0

[root@localhost ~]#

条件语句

Shell 具有一般高级语言所具有的控制结构,如 if 语句、 case 语句

1.     if 语句

if 语句可根据表达式的值是真或假来决定要执行的程序段落,其语法如下:

if expressionl  // expressionl 为真

then

commands     // 则执行这些命令

elif expression2  // 否则若 expression2 为真

then

commands     // 则执行这些命令

else   // 若以上的表达式都不成立

commands  // 则执行这些命令

fi   // 结束 if 语句

fi   // 结束 if 语句

 

fi if 语句的结束符(刚好是 if 倒过来) , 必须与 if 成对出现,而 elif else 子句可有可无。 Elif else if 的简写,当 if 的表达式不成立时,才会接着测试 elif 的表达式。如果子句,但只能有一个 else 子句。

[root@localhost ~]# vim aaa

// 建立一个脚本文件,命名为 aaa

[root@localhost ~]# sh aaa

// 执行 aaa, 没有文件,或同名但是不是文件

no example_if file in current directory.

[root@localhost ~]# touch example_if

// 建立文件名为 example_if

[root@localhost ~]# sh aaa

// 执行 aaa, 显示正确

There is a example_if file in current directory.

[root@localhost ~]# cat -n aaa

     1  #!/bin/bash

     2  if [ -f example_if ] // 判断 example_if 是不是文件

     3  then

     4  echo "There is a example_if file in current directory."  // 如果是,显示 There is a example_if file in current directory

     5  else

     6  echo "no example_if file in current directory."   // 否则,显示 no example_if file in current directory    

7  fi

     8  #end

[root@localhost ~]#