Shell编程-分支语句(1)
1.返回值
shell变量“?”中保存上一个被执行命令的返回值:
0: 命令成功地执行(真)
非零: 命令由于出现错误而被终止(假)
例子:
$ true $ false
$ echo $? $ echo $?
0 1
$ ls $ cp
$ echo $? Usage: cp f1 f2
0 cp [-r] f1 ....fn d1
$ echo $? $echo $?
0 1
$echo $?
0
UNIX操作系统的所有命令在结束的时候都会产生一个返回值。这个返回值通常被用来判断命令是正常结束(返回0)还是发生了错误(返回非零值)。通过返回的非零值还可以看出发生的是什么错误。例如,语法错误通常返回1,true命令返回的就是0,而false命令返回的是1。
大多数的shell程序中的判断语句都是通过分析这个返回值来进行流程控制的。shell中定义了一个特殊的变量“?”用来保存上一个命令结束后的返回值。
你可以通过以下方式来观察前一个命令的返回值:
echo $?
当你执行一个条件判断(小于,大于,等于)的时候,返回值会指明这个条件是否为真(返回0)或者为假(返回非零)。
条件判断语句会在下几节中讲述。
2.test 命令
语法:
test expression 或者 [expression]
test命令对表达式进行测试,并且设置返回值。
表达式的值 返回值
true 0
false 非零(通常为1)
test命令能够测试的对象有:
整数
字符串
文件
test命令被用来评估表达式并且产生返回值。它用参数组成逻辑表达式并且对表达式的返回值进行评估,test命令不会产生标准输出,你必须必须通过返回值来判断test命令的结果,如果表达式为真,返回值会为0,如果表达式为假,返回值为1。
test命令可以被单独使用,然后你能够看到返回值,但它用的最多的还是在if和while结构中用来提供条件流程控制。
test命令的也可以用[expression]来代替。这种方式可以提高可读性,特别是在处理数字或者字符串的时候。
注意:在"["和"]"符号的周围必须要有空格。
3.test命令之数字test
语法:
[ number relation number ] 通过关系运算符来对数字进行比较
关系运算符:
-lt 小于
-le 小于或者等于
-gt 大于
-ge 大于或者等于
-eq 等于
-ne 不等于
例子(假设X=3):
$ [ "$X" -lt 7] $ [ "$X" -gt 7]
$ echo $? $ echo $?
0 1
test命令能被用于比较两个整数之间的数字关系,通常用[.....]语法来调用。test命令的返回值就能说明这个条件为真还是为假。
当test一个变量的值的时候,你应该防止变量不要为空值,例如:
$ [ $XX -eq 3]
sh: test:argument expected
如果变量XX在前面没有被赋值,XX的值会是NULL。当shell执行变量替代的时候,shell会试图执行如下语句:
[ -eg 3]
而这个语句不是一个完整的test语句,并且会导致一个语法错误。解决这个问题的一个简单的方法就是在被测试的变量的周围加上引号。
[ "$XX" -eq 3]
当shell执行变量替代的时候,shell会试图执行如下语句:
["" -eq 3]
这会确保至少有一个NULL值作为一个参数提供给这个test命令使用。
注意:作为一个通用的规则,你应该在所有的$变量加上双引号来避免shell发生不正确的变量的替代。
4.test命令-字符串test
语法:
[ string1 = string2] 判断字符串是否相等
[ string1 !=string2] 判断字符串是否不等
例子;
$ X=abc $ X=abc
$ [ "$X" = "abc"] $ ["$X" != "abc"]
$ echo $? $ echo $?
0 1
test命令也能够用来计较两个字符串是否相等。
[...] 语法通常用作字符串的比较。你已经看到在[]周围必须要有空格,同时在操作符周围也必须要有空格存在。
字符串操作包括:
string1 = string2 如果string1等于string2就为真
string1 != string2 如果string1不等于string2就为真
-z string 如果string的长度为0就为真
-n string 如果string的长度为非零就为真
string 如果string的长度为非零就为真
为了防止变量中包含空白字符,这里引号同样也能够保护字符串的test,,例如:
$ X="yes we will"
$ [ $X=yes] 会导致一个语法错误
shell会解释这个语句为[yes we will = yes ]
$ [ "$x" = yes ] 正确的语法
shell会解释这个语句为:[ "yes we will" = yes ]
在执行数字比较的时候,shell会将所有的参数当成是数字,在执行字符串比较的时候,shell会把所有的参数当成是字符串。如下例所示:
$ X=03
$ Y=3
$ [ "$X" -eq "$Y" ] 比较数字03和数字3
$ echo $?
0 为真,因为它们是相等的数字
$ [ "$X" = "$Y" ] 比较字符串“03”和字符串“3”
$ echo $?
1 为假,因为它们是不相同的字符串
5.test命令- 文件比较
语法:
test -option filename 通过选项对文件进行test
例子:
$ test -f funfile
$ echo $?
0
$ test -d funfile
$ echo $?
1
shell提供的一个有用的test特性是可以用它来test文件的特征,例如文件类型和许可权限。例如:
$ test -f filename
如果文件存在并且是一个普通文件(不是目录或者设备文件),会返回真(0)。
test -s filename
如果文件存在并且其字节数大于0,会返回真(0)。
其它还有许多有用的文件test方式,比如:
-r file 如果文件存在并且是可读的时候为真
-w file 如果文件存在并且是可写的时候为真
-x file 如果文件存在并且是可执行的时候为真
-d directory 目录存在并且是个目录的时候为真
6.test命令-其他操作符
语法:
-o OR
-a AND
\( \) GROUPING
例子:
$ [ "$ANS" = y -o "ANS' = Y ]
$ [ "$NUM -gt 10 -a "$NUM" -lt 20 ]
$ test -s file -a -r file
注意:()前面必须要用斜杠。
使用Boolean操作符可以同时测试多个条件。
例子:
$ [ "$ANS" = y -o "$ANS" = Y ]
$ [ "$NUM" -gt 10 -a "$NUM" -lt 20 ]
$ test -s file -a -r file -a -x file
NOT操作符(!)被用作连接其他的操作符,特别是在文件test的时候用的很普遍。在!操作符和其他的操作符之间必须要有空格,例如:
test ! -d file
能够用来代替
test -f file -o -c file -o -b file ....
括号被用来对操作符进行分组,但是在shell中括号还有一个特殊的意义就是优先运算的意义。因此,括号前面必须使用\符号来忽略其原有含义。
以下的命令验证:有两个命令行参数,并且第一个命令行参数是一个-m ,并且最后一个命令行参数是一个目录或者是一个字节数大于0的文件:
[ \( $# = 2 \) -a \( "$1" = "-m" \) -a \( -d "$2" -o -s "$2" \) ]
7.exit命令
语法:
exit [arg]
例子:
$ cat exit_test
echo exiting program now
exit 99
$ exit_test
exiting_program now
$ echo $?
99
exit命令结束当前shell程序的执行并且设置返回值。通常0被用来说明正常结束,而非0值用来说明一个错误的条件。如果没有特别指明返回值,返回值将被设置为exit命令上一个命令的返回值。