TEST
条件测试语句经常会被脚本中的控制结构所调用,常用命令有两个,test和expr,有时我们甚至都不知道自己在使用test,这是因为test有两种结构,一种是常规的
$test condition
另一种比较常用的表达式为
[ condition ]
中括号和condition之间一定要有空格
test主要用途是对字符串、整数以及文件进行条件判断,对于判断结果可以通过
$echo $?
来查看,返回结果为0则表示真,为1则表示假,为2则表示参数不正确
特殊变量列表
$0 正在被执行命令的名字。对于shell脚本而言,这是被激活命令的路径
$n 该变量与脚本被激活时所带的参数相对应。n是正整数,与参数位置相对应($1,$2...)
$# 提供脚本的参数数量
$* 所有这些参数都被双引号引住。若一个脚本接收两个参数,$*等于$1$2
$@ 所有这些参数都分别被双引号引住。若一个脚本接收到两个参数,$@等价于$1 $2
上面这两个的区别不是很清楚,虽然表达的很明确,但是应用中的区别没有很好的例子,多数是用在for中对当前所输入参数进行循环,注意$1和$2之间存在一个空格
$? 前一个命令执行后的退出状态
$$ 当前shell的进程号。对于shell脚本,这是其正在执行时的进程ID
$! 前一个后台命令的进程号
test操作字符串
string
-z string 若string长度为0,则为真
-n string 若string长度不为0,则为真
string1 = string2 若两个字符串相等,则为真
string1 != string2 若两个字符串不相等,则为真
test操作整数
integer
int1 -eq(ual) int2 若int1等于int2,则为真
int1 -ne int2 若int1不等于int2,则为真
int1 -lt int2 若int1小于int2,则为真
int1 -le int2 若int1小于等于int2,则为真
int1 -gt int2 若int1大于int2,则为真
int1 -ge int2 若int1大于等于int2,则为真
test操作文件
file
相同: -ef 索引节点号相同
新 : -nt modified date
旧 : -ot modified date
-b : 块设备
-c : 字符设备
-d : 目录
-f : 规则文件
-e : 文件存在
-r : 文件可读
-w : 文件可写
-x : 文件可执行
-h -L: link文件
-s : 文件存在并且大小大于0
-S : 文件存在并且是个socket
-p : 文件存在并且是个named pipe
-G : 文件存在并且设置了有效的gid
-O : 文件存在并且设置了有效的uid
-g : 文件存在并且设置了sgid
-u : 文件存在并且设置了suid
-k : 文件存在并且设置了粘滞位
-t : 文件描述符
在使用时如果涉及到变量的引用,最好加上"",否则在字符串为空的情况下会出现异常情况
举例说明
$ a=1 + a=1
$ b=2 + b=2
$ [ -z $a -o -z $b ]
$ echo $? + echo 1
1
$ b= + b=
$ [ -z "$a" -o -z "$b"
$ echo $? + echo 0
0
$ [ -z $a -o -z $b ]
-bash: [: argument expected
$ echo $? + echo 2
2
逻辑操作符
-a :逻辑与,操作符两边均为真,结果为真,否则为假。
-o :逻辑或,操作符两边一边为真,结果为真,否则为假。
!:逻辑否,条件为假,结果为真。
EXPR
expr命令一般用于整数值,但也可用于字符串的计算,使用方法如下
以下出现的所有\字符皆为转意符号,防止shell扩展
expr ARG1 \| ARG2 ARG1不是空值或0值的话返回ARG1,否则返回ARG2
expr ARG1 \& ARG2 如果两个表达式都不是空值或者0值返回ARG1,否则返回0
比较运算:ARG1 <,>,<=,>=,=,!= ARG2 其中<,>,<=,>=运算都必须加\防止shell扩展
需要注意的一点是expr的结果与命令的状态返回值恰恰相反,即判断结果为真时返回1,为假时返回0,如
$ expr 1 = 1
1
$ echo $?
0
数值运算:ARG1 +,-,*,/,% ARG2 其中*需要加\
STRING : REGEXP 将STRING中的字符串与正则表达式进行比较,返回匹配的字符个数,没有匹配返回0,当REGEXP中包含子表达式时\(...\)时,返回包含实际匹配的字符串
eg:
$VALUE=accounts.doc
$expr "$VALUE" : ".*"
12
$expr "$VALUE" : "\(.*\).doc"
accounts
match STRING REGEXP 与STRING:REGEXP相同
substr STRING POS LENGTH字符串截取,截取STRING的第POS个字符开始,长度为length的字符串
$expr substr "Goodnight Ladies" 11 6
Ladies
index STRING CHARS 返回STRING中的包含CHARS中的第一个字符位置,如果没有则返回0
$expr index abcdef de
4
$expr index abcdef fd
4
length STRING 计算字符串的长度
$echo $VALUE
accounts.doc
$expr length "$VALUE"
12
在使用时如果涉及到shell变量,建议要用“”括起来,否则空串会有问题
如上面最后的例子
$VALUE=
$expr length $VALUE
expr: syntax error
当然在极特殊的时候即使加上""仍然有问题,如在某些系统中(我用于测试的RHAS4没有该问题,仅作记录)
$STR="="
$expr "$STR" = "="
此时就会报语法错误,一旦shell变量的值与 expr运算符中的一个相同,这种情况就会发生。避免这种问题的方法是,将该表达式写成:
$expr "x$STR" = "x="即可