单方括号的test命令 通常用内置的test命令来测试表达式的值,test命令也被链接到方括号上。这样,既可以使用单独的test命令,也可以通过把表达式用单方括号括起来,来测试表达式的值。在用test命令或方括号测试表达式时,表达式中的shell元字符不会被扩展。由于要对变量进行单词分离,因此包含空白符的字符串必须用引号括起来(参见范例14-16)。
双方括号的test命令 2.x版bash中,用双方括号 [[ ]](内置的test复合命令)来测试表达式的值,其中,对变量不进行单词分离,但可以通过元字符扩展进行模式匹配。包含空白符的字符串必须用引号括起来。如果一个字符串(不管含不含空白符)仅仅是在表达式中作为一个普通字符串,而不是一个模式的一部分,则它也必须用引号括起来。逻辑操作符&&(与)和| | (或)代替了与test命令一起使用的-a和-o选项(参见范例14-17)。
范例
14-16
(test
命令
)
(
命令行
)
1 $ name=Tom
2 $ grep "$name" /etc/passwd
3 $ echo $?
4 $ test $name != Tom
5 $ echo $?
1 # Failure
6 $ [ $name = Tom ] # Brackets replace the test command
7 $ echo $?
0
8 $ [ $name = [Tt]?? ]
$ echo $?
1
9 $ x=5
$ y=20
10 $ [ $x -gt $y ]
$ echo $?
1
11 $ [ $x -le $y ]
$ echo $?
0
说明
1.
变量
name
被赋值为字符串
Tom
。
2. grep
命令在文件
passwd
中查找字符串
Tom
。
3.
变量
“
?
”
包含
shell
执行的上一条命令的退出状态,本例中是
grep
命令的退出状态。如果
grep
成功地找到了字符串
Tom
,就返回退出状态
0
。这条
grep
命令执行成功。
4. test
命令可用于测试字符串和数字,也可用来执行文件测试。和所有的命令一样,
test
也会返回一个退出状态:退出状态为
0
,则表达式为真,退出状态为
1
,则表达式为假。表达式的等号两侧必须有空格。这条命令测试
name
的值是否等于
Tom
。
5.
测试失败,
test
返回的退出状态为
1
。
6.
方括号是
test
命令的另一种表示方式。第一个方括号后面必须跟空格。这里的表达式测试变量
name
的值是否为字符串
Tom
。
Bash
中既可以使用单等号来测试字符串是否相等,也可以使用双等号来进行测试。
7. test
的返回值是
0
。因为变量
name
的值等于
Tom
,所以
test
执行成功。
8. test
命令不允许通配符展开。由于问号被当作一个普通字符,因此
test
执行失败,
Tom
与
[Tt]??
不相等。返回状态为
1
,表示该表达式测试失败。
9.
给
x
和
y
赋数值。
10. test
命令使用数值关系操作符进行测试。本例中,
test
命令检测
$x
是否大于
$y
,如果是则返回
0
,否则,返回
1(
见表
14-3)
。
11. test
命令检测
$x
是否小于或等于
$y
,如果是则返回
0
,否则,返回
1
。
表
14-3 test
命令操作符
操
作
符
|
测
试
内
容
|
字符串测试
| |
[ string1 = string2 ]
|
string1
等于
string2(=
两侧必须有空格
)
|
[ string1= = string2 ]
|
string1
等于
string2(
在
2.x
版
bash
中可以用单等号
=
代替
)
|
[ string1 != string2 ]
|
string1
不等于
string2(!=
两侧必须有空格
)
|
[ string ]
|
string
不为空
|
[ -z string ]
|
string
的长度为
0
|
[ -n string ]
|
string
的长度不为
0
|
[ -l string ]
|
string
的长度
(
字符数
)
例如:
test –n $word
或
[ -n $word ]
test tom = sue
或
[ tom = sun ]
|
逻辑测试
| |
[ string1 –a string2 ]
|
string1
和
string2
都为真
|
[ string1 –o string2 ]
|
string1
或
string2
至少有一个为真
|
[ !string1 ]
|
字符串不匹配
|
逻辑测试
(
复合命令
)
⑦
| |
[[ pattern1 && pattern2 ]]
|
pattern1
和
pattern2
都为真
|
[[ pattern1 || pattern2 ]]
|
pattern1
或
pattern2
至少有一个为真
|
[[ !pattern1 ]]
|
模式不匹配
|
整数测试
| |
[ int1 –eq int2 ]
|
int1
等于
int2
|
[ int1 –ne int2 ]
|
int1
不等于
int2
|
[ int1 –gt int2 ]
|
int1
大于
int2
|
[ int1 –ge int2 ]
|
int1
大于或等于
int2
|
[ int1 –lt int2 ]
|
int1
小于
int2
|
[ int1 –le int2 ]
|
int1
小于或等于
int2
|
用于文件测试的二进制操作符
| |
[ file1 –nt file2 ]
|
如果文件
file1
比
file2
新则为真
(
根据修改时间
)
|
[ file1 –ot file2 ]
|
如果文件
file1
比
file2
老则为真
|
[ file1 –ef file2 ]
|
如果文件
file1
和
file2
有相同的设备数或
i
结点数则为真
|
范例
14-17
(
复合的
test
命令
)(bash2.x)
$ name=Tom; friend=Joseph
1 $ [[ $name == [Tt]om ]] # Wildcards allowed
$ echo $?
0
2 $ [[ $name == [Tt]om && $friend == "Jose" ]]
$ echo $?
1
3 $ shopt -s extglob # Turns on extended pattern matching
4 $ name=Tommy
5 $ [[ $name == [Tt]o+(m)y ]]
$ echo $?
0
说明
1.
如果使用复合的
test
命令,在字符串测试中可以使用
shell
元字符。本例中的表达式将进行字符串相等测试,看变量
name
是否匹配于
Tom
、
tom
或
tommy
等。表达式为真,则退出状态
(?)
为
0
。
2.
逻辑操作符
&&(
与
)
和
| | (
或
)
可以与复合的
test
命令一起使用。如果是
&&
操作,两边的表达式必须都为真,如果第一个表达式测试为假,则不再进行进一步测试。而对于
| |
逻辑操作符,两个表达式中有一个为真即可,如果第一个表达式测试为真,则不再进行进一步测试。注意:
“Jose”
是被引号括起来的,如果不使用引号,则是测试变量
friend
是否包含模式
Jose
。
Jose
和
Joseph
都满足条件。这里第二个条件非真,表达式测试为假,退出状态为
1
。
3.
用内置的
shopt
命令打开扩展的模式匹配开关。
4.
变量
name
被赋值为
Tommy
。
5.
测试表达式是否相等,包含模式匹配元字符。测试变量
name
是否匹配于一个字符串:它以字母
T
或
t
开头、后跟字母
o
、接着是一个或多个字母
m
,最后跟字母
y
。
后面的范例将说明如何使用内置的test命令、带单方括号的test命令,以及带双方括号的复合命令来测试退出状态。
let
命令和带双圆括号的算术运算 虽然test命令可以计算算术表达式的值,但读者可能更愿意使用let命令,因为let命令带有丰富的类C操作符(bash 2.x)。let命令可以将表达式包含在一组圆括号中来表达不同的含义。
不管使用的是test命令、复合命令还是let命令,表达式的结果都会被测试。返回零表示成功,而返回非零状态表示失败(参见表14-4)。
表
14-4 let
命令操作符
操
作
符
|
含
义
|
-
+
!
~
*
/
%
+
-
|
负号
正号
逻辑非
按位取反
乘法
除法
余数
加法
减法
|
(续表)
操
作
符
|
含
义
|
<<
>>
<= >= < >
== !=
&
^
|
&&
| |
= *= /= %= += -= <<= >>= &= ^= |=
|
按位左移
按位右移
关系运算符
相等、不相等
按位与操作
按位异或操作
按位或操作
逻辑与
逻辑或
赋值、快捷赋值运算符
|
范例14-18说明了let命令中如何使用双圆括号。
范例
14-18
(let
命令
)(bash2.x)
(
命令行
)
1 $ x=2
$ y=3
2 (( x > 2 ))
echo $?
1
3 (( x < 2 ))
echo $?
0
4 (( x == 2 && y == 3 ))
echo $?
0
5 (( x > 2 || y < 3 ))
echo $?
1
说明
1.
给
x
和
y
赋值。
2.
双圆括号代替
let
命令来测试数值表达式。如果
x
比
y
大,退出状态为
0
。由于条件不满足,因此退出状态为
1
。变量
?
包含上一条执行命令的退出状态,这里是
(( ))
命令的退出状态。注意,括在
(( ))
中的变量不需要使用美元符
$
。
3.
用双圆括号测试表达式。如果
x
小于
2
,则返回退出状态
0
,否则,返回
1
。
4.
测试复合表达式:如果
x
等于
2
且
y
等于
3(
即两个表达式都为真
)
,则退出状态返回
0
,否则,返回
1
。
5.
测试复合表达式:如果
x
大于
2
或
y
小于
3(
即有一个表达式为真
)
,则退出状态返回
0
,否则,返回
1
。