Linux Shell常用技巧(十二)

  • A+
所属分类:System

二十三. Bash Shell编程:
1. 读取用户变量:
read命令是用于从终端或者文件中读取输入的内建命令,read命令读取整行输入,每行末尾的换行符不被读入。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY。下面的列表给出了read命令的常用方式:

命令格式 描述
read answer 从标准输入读取输入并赋值给变量answer。
read first last 从标准输入读取输入到第一个空格或者回车,将输入的第一个单词放到变量first中,并将该行其他的输入放在变量last中。
read 从标准输入读取一行并赋值给特定变量REPLY。
read -a arrayname 把单词清单读入arrayname的数组里。
read -p prompt 打印提示,等待输入,并将输入存储在REPLY中。
read -r line 允许输入包含反斜杠。

见下面的示例(绿色高亮部分的文本为控制台手工输入信息):

2. 状态判断:
test是Shell中提供的内置命令,主要用于状态的检验,如果结果为0,表示成功,否则表示失败。见如下示例:

下面的表格是test命令支持的操作符:

判断操作符 判断为真的条件
字符串判断
[ stringA=stringB ] stringA等于stringB
[ stringA==stringB ] stringA等于stringB
[ stringA!=stringB ] stringA不等于stringB
[ string ] string不为空
[ -z string ] string长度为0
[ -n string ] string长度不为0
逻辑判断
[ stringA -a stringB ] stringA和stringB都是真
[ stringA -o stringB ] stringA或stringB是真
[ !string ] string不为真
逻辑判断(复合判断)
[[ pattern1 && pattern2 ]] pattern1和pattern2都是真
[[ pattern1 || pattern2 ] pattern1或pattern2是真
[[ !pattern ]] pattern不为真
整数判断
[ intA -eq intB ] intA等于intB
[ intA -ne intB ] intA不等于intB
[ intA -gt intB ] intA大于intB
[ intA -ge intB ] intA大于等于intB
[ intA -lt intB ] intA小于intB
[ intA -le intB ] intA小于等于intB
文件判断中的二进制操作
[ fileA -nt fileB ] fileA比fileB新
[ fileA -ot fileB ] fileA比fileB旧
[ fileA -ef fileB ] fileA和fileB有相同的设备或者inode值
文件检验
[ -d $file ] or [[ -d $file ]] file为目录且存在时为真
[ -e $file ] or [[ -e $file ]] file为文件且存在时为真
[ -f $file ] or [[ -f $file ]] file为非目录普通文件存在时为真
[ -s $file ] or [[ -s $file ]] file文件存在, 且长度不为0时为真
[ -L $file ] or [[ -L $file ]] file为链接符且存在时为真
[ -r $file ] or [[ -r $file ]] file文件存在且可读时为真
[ -w $file ] or [[ -w $file ]] file文件存在且可写时为真
[ -x $file ] or [[ -x $file ]] file文件存在且可执行时为真

注:在逻辑判断(复合判读中),pattern可以包含元字符,在字符串的判断中,pattern2必须被包含在引号中。
let命令支持的操作符和C语言中支持的操作符完全相同,如:

3. 流程控制语句:
if语句格式如下:
#if语句的后面是Shell命令,如果该命令执行成功返回0,则执行then后面的命令。

#用test命令测试其后面expression的结果,如果为真,则执行then后面的命令。

#下面的格式和test expression等同

#下面的两种格式也可以用于判断语句的条件表达式,而且它们也是目前比较常用的两种。

见如下示例:

下面的例子将使用Shell中的扩展通配模式。

对于本示例中的扩展通配符,这里需要给出一个具体的解释。[Nn]o匹配No或no,?( way|t really)则表示0个或1个( way或t really),因此answer变量匹配的字符串为No、no、Not really、not really、No way、no way。
下面的示例使用了let命令操作符,如:

下面的示例为如何在if的条件表达式中检验空变量:

见如下示例脚本:

case语句格式如下:

见如下示例脚本:

4. 循环语句:
Bash Shell中主要提供了三种循环方式:for、while和until。
for循环声明格式:

见如下示例脚本:

while循环声明格式:

见如下示例脚本:

shift命令声明格式:shift [n]
shift命令用来把脚本的位置参数列表向左移动指定的位数(n),如果shift没有参数,则将参数列表向左移动一位。一旦移位发生,被移出列表的参数就被永远删除了。通常在while循环中,shift用来读取列表中的参数变量。
见如下示例脚本:

break命令声明格式:break [n]
和C语言不同的是,Shell中break命令携带一个参数,即可以指定退出循环的层数。如果没有指定,其行为和C语言一样,即退出最内层循环。如果指定循环的层数,则退出指定层数的循环体。如果有3层嵌套循环,其中最外层的为1,中间的为2,最里面的是3。
见如下示例脚本:

continue命令声明格式:continue [n]
和C语言不同的是,Shell中continue命令携带一个参数,即可以跳转到指定层级的循环顶部。如果没有指定,其行为和C语言一样,即跳转到最内层循环的顶部。如果指定循环的层数,则跳转到指定层级循环的顶部。如果有3层嵌套循环,其中最外层的为3,中间的为2,最里面的是1。

I/O重新定向和子Shell:
文件中的输入可以通过管道重新定向给一个循环,输出也可以通过管道重新定向给一个文件。Shell启动一个子Shell来处理I/O重新定向和管道。在循环终止时,循环内部定义的任何变量对于脚本的其他部分来说都是不看见的。

5. IFS和循环:
Shell的内部域分隔符可以是空格、制表符和换行符。它可以作为命令的分隔符用在例如read、set和for等命令中。如果在列表中使用不同的分隔符,用户可以自己定义这个符号。在修改之前将IFS原始符号的值保存在另外一个变量中,这样在需要的时候还可以还原。
见如下示例脚本:

6. 函数:
Shell中函数的职能以及优势和C语言或其它开发语言基本相同,只是语法格式上的一些差异。下面是Shell中使用函数的一些基本规则:
1) 函数在使用前必须定义。
2) 函数在当前环境下运行,它和调用它的脚本共享变量,并通过位置参量传递参数。而该位置参量将仅限于该函数,不会影响到脚本的其它地方。
3) 通过local函数可以在函数内建立本地变量,该变量在出了函数的作用域之后将不在有效。
4) 函数中调用exit,也将退出整个脚本。
5) 函数中的return命令返回函数中最后一个命令的退出状态或给定的参数值,该参数值的范围是0-256之间。如果没有return命令,函数将返回最后一个Shell的退出值。
6) 如果函数保存在其它文件中,就必须通过source或dot命令把它们装入当前脚本。
7) 函数可以递归。
8) 将函数从Shell中清空需要执行:unset -f function_name。
9) 将函数输出到子Shell需要执行:export -f function_name。
10) 可以像捕捉Shell命令的返回值一样获取函数的返回值,如$(function_name)。
Shell中函数的声明格式如下:

见如下示例脚本:

7. 陷阱信号(trap):
在Shell程序运行的时候,可能收到各种信号,有的来自于操作系统,有的来自于键盘,而该Shell在收到信号后就立刻终止运行。但是在有些时候,你可能并不希望在信号到达时,程序就立刻停止运行并退出。而是他能希望忽略这个信号而一直在运行,或者在退出前作一些清除操作。trap命令就允许你控制你的程序在收到信号以后的行为。
其格式如下:

后面的两种形式主要用于信号复位,即恢复处理该信号的缺省行为。还需要说明的是,如果trap后面的命令是使用单引号括起来的,那么该命令只有在捕获到指定信号时才被执行。如果是双引号,则是在trap设置时就可以执行变量和命令替换了。
下面是系统给出的信号数字和信号名称的对照表:

见如下示例脚本:

8. 用getopts处理命令行选项:
这里的getopts命令和C语言中的getopt几乎是一致的,因为脚本的位置参量在有些时候是失效的,如ls -lrt等。这时候-ltr都会被保存在$1中,而我们实际需要的则是三个展开的选项,即-l、-r和-t。见如下带有getopts的示例脚本:

9. eval命令与命令行解析:
eval命令可以对命令行求值,做Shell替换,并执行命令行,通常在普通命令行解析不能满足要求时使用。

转载于:http://www.cnblogs.com/stephen-liu74/archive/2011/12/19/2265416.html

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: