码迷,mamicode.com
首页 > 系统相关 > 详细

Bourne Shell中的条件判断

时间:2015-12-21 00:03:51      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:

    条件判断是一个程序获得智能的基础,而Bourne Shell脚本则通过命令 [ 来模拟大多数编程语言中的条件表达式。

    shell中支持的控制结构有:

(1) if then else fi

(2) for in do done

(3) while do done

    第二种主要用于遍历,可能不需要条件判断,其它两种则免不了和 [ 命令共同使用了。下面讲解这个命令如何模拟条件表达式。

 

文件/目录判断
[ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真。
[ -c FILE ] 如果 FILE 存在且是一个字特殊文件则为真。
[ -d DIR ] 如果 FILE 存在且是一个目录则为真。
[ -e FILE ] 如果 FILE 存在则为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。
[ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。
[ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。
[ -p FILE ] 如果 FILE 存在且是一个名字管道(F如果O)则为真。
[ -r FILE ] 如果 FILE 存在且是可读的则为真。
[ -s FILE ] 如果 FILE 存在且大小不为0则为真。
[ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。
[ -w FILE ] 如果 FILE存在且是可写的则为真。
[ -x FILE ] 如果 FILE 存在且是可执行的则为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。
[ -G FILE ] 如果 FILE 存在且属有效用户组则为真。
[ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。
[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1 exists and FILE2 does not则为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。

 

字符串判断
[ -z STRING ] 如果STRING的长度为零则为真 ,即判断是否为空,空即是真;
[ -n STRING ] 如果STRING的长度非零则为真 ,即判断是否为非空,非空即是真;
[ STRING1 = STRING2 ] 如果两个字符串相同则为真 ;
[ STRING1 != STRING2 ] 如果字符串不相同则为真 ;
[ STRING1 ]  如果字符串不为空则为真,与-n类似

 

数值判断
INT1 -eq INT2 INT1和INT2两数相等为真 ,=
INT1 -ne INT2 INT1和INT2两数不等为真 ,<>
INT1 -gt INT2 INT1大于INT1为真 ,>
INT1 -ge INT2 INT1大于等于INT2为真,>=
INT1 -lt INT2 INT1小于INT2为真 ,<
INT1 -le INT2 INT1小于等于INT2为真,<=

总之,“=”用于比较字符串;“-eq”用于比较整型数

 

复杂逻辑判断
-a 与
-o 或
! 非

1、如果a>b且a<c
if (( a > b )) && (( a < c ))
if [[ $a > $b ]] && [[ $a < $c ]]
if [ $a -gt $b -a $a -lt $c ]

2、如果a>b或a<c
if (( a > b )) || (( a < c ))
if [[ $a > $b ]] || [[ $a < $c ]]
if [ $a -gt $b -o $a -lt $c ]

"||"和"&&"在SHELL里可以用,第一个可以写成if [ a>b && a ]

 双括号和双中括号的含义见下文中对各种括号的解释。

 

Shell中的括号(), (()), [], [[]]

1、单小括号 ()
①命令组。括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。
②命令替换。等同于`cmd`,shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。
③用于初始化数组。如:array=(a b c d)

2、双小括号 (( ))
①整数扩展。这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为1,或者 是"假",而一个非零值的表达式所返回的退出状态码将为0,或者是"真"。
②只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中。作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。如:echo $((16#5f)) 结果为95 (16进位转十进制)。单纯用 (( )) 也可重定义变量值,比如 a=5; ((a++)) 可将 $a 重定义为6。双括号中的变量可以不使用$符号前缀。括号内支持多个表达式用逗号分开。
③甚至可以替代循环结构,只要括号中的表达式符合C语言运算规则。比如可以直接使用for((i=0;i<5;i++)), 如果不使用双括号, 则为for i in `seq 0 4`或者for i in {0..4}。再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]。

3、单中括号 []
①标准命令 [ 和 test 是具有相同作用,区别在于 [ 命令的最后一个参数是 "]" 。
②在正则表达式中用于表示字符范围。作为test用途的中括号内不能使用正则。
④在一个array 结构的上下文中,中括号用来引用数组中每个元素的编号。

4、双中括号[[ ]]
①[[是 bash 程序语言的关键字,并不是一个命令。[[ ]] 结构比[ ]结构更加通用,不过注意[[ 依然要和中括号内的内容用空格隔开。
②支持字符串的模式匹配,使用=~操作符时支持正则表达式,使用==操作符时则支持通配符,字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。
③使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错,原因是 [ 命令不能解释&&的含义。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果使用单括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。
④bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。

 

关于shell的其它

shell有时靠命令来模拟运算。例如四则运算可以借助:let, expr 等命令完成。如对变量 x 加 1 可以写作:let "x = $x + 1" 或者 x=`expr $x + 1‘ 。如果参数有空格,一定要用引号括起来才不会出错。空格在shell中是有意义的。

PS:注意shell中,所有的输入都是字符串类型(当然任何语言都是如此,只是shell支持的类型解释和转换比较少),其中美元符$ 反引号` 反斜线\ 都被sh进程或者bash进程解释成字符串替换或命令替换,也就是用特定的输出字符串替换原命令,然后再继续执行新的命令。

 

调试:

查看shell脚本的执行过程
在执行的时候,通过下面的方式:
#sh -x test.sh

 

获取参数:

$# 是传给脚本的参数个数
$0 是脚本本身的名字
$1 是传递给该shell脚本的第一个参数
$2 是传递给该shell脚本的第二个参数
$@ 是传给脚本的所有参数的列表
$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
$$ 是脚本运行的当前进程ID号
$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

 

Bourne Shell中的条件判断

标签:

原文地址:http://www.cnblogs.com/xinchrome/p/5062017.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!