[[ $a == z* ]] # $a 以 "z" 开头时为真(模式匹配)
[[ $a == "z*" ]] # $a 等于 z* 时为真(字符匹配)
[ $a == z* ] # 发生文件匹配和字符分割。
[ "$a" == "z*" ] # $a 等于 z* 时为真(字符匹配)
# 感谢 Stéphane Chazelas
String='' # 长度为0的字符串变量。
if [ -z "$String" ]
then
echo "\$String is null."
else
echo "\$String is NOT null."
fi # $String is null.
样例 7-5. 算术比较和字符串比较
#!/bin/bash
a=4
b=5
# 这里的 "a" 和 "b" 可以是整数也可以是字符串。
# 因为 Bash 的变量是弱类型的,因此字符串和整数比较有很多相同之处。
# 在 Bash 中可以用处理整数的方式来处理全是数字的字符串。
# 但是谨慎使用。
echo
if [ "$a" -ne "$b" ]
then
echo "$a is not equal to $b"
echo "(arithmetic comparison)"
fi
echo
if [ "$a" != "$b" ]
then
echo "$a is not equal to $b."
echo "(string comparison)"
# "4" != "5"
# ASCII 52 != ASCIII 53
fi
# 在这个例子里 "-ne" 和 "!=" 都可以。
echo
exit 0
样例 7-6. 测试字符串是否为空(null
)
#!/bin/bash
# str-test.sh: 测试是否为空字符串或是未引用的字符串。
# 使用 if [ ... ] 结构
# 如果字符串未被初始化,则其值是未定义的。
# 这种状态就是空 "null"(并不是 0)。
if [ -n $string1 ] # 并未声明或是初始化 string1。
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi
# 尽管没有初始化 string1,但是结果显示其非空。
echo
# 再试一次。
if [ -n "$string1" ] # 这次引用了 $string1。
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi # 在测试括号内引用字符串得到了正确的结果。
echo
if [ $string1 ] # 这次只有一个 $string1。
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi # 结果正确。
# 独立的 [ ... ] 测试运算符可以用来检测字符串是否为空。
# 但是最好将字符串进行引用(if [ "$string1" ])。
#
# Stephane Chazelas 指出:
# if [ $string1 ] 只有一个参数 "]"
# if [ "$string1" ] 则有两个参数,空的 "$string1" 和 "]"
echo
string1=initialized
if [ $string1 ] # $string1 这次仍然没有被引用。
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi # 这次的结果仍然是正确的。
# 最好将字符串引用("$string1")
string1="a = b"
if [ $string1 ] # $string1 这次仍然没有被引用。
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi # 这次没有引用就错了。
exit 0 # 同时感谢 Florian Wisser 的提示。
样例 7-7. zmore
#!/bin/bash
# zmore
# 使用筛选器 'more' 查看 gzipped 文件。
E_NOARGS=85
E_NOTFOUND=86
E_NOTGZIP=87
if [ $# -eq 0 ] # 作用和 if [ -z "$1" ] 相同。
# $1 可以为空: zmore "" arg2 arg3
then
echo "Usage: `basename $0` filename" >&2
# 将错误信息通过标准错误 stderr 进行输出。
exit $E_NOARGS
# 脚本的退出状态为 85.
fi
filename=$1
if [ ! -f "$filename" ] # 引用字符串以防字符串中带有空格。
then
echo "File $filename not found!" >&2 # 通过标准错误 stderr 进行输出。
exit $E_NOTFOUND
fi
if [ ${filename##*.} != "gz" ]
# 在括号内使用变量代换。
then
echo "File $1 is not a gzipped file!"
exit $E_NOTGZIP
fi
zcat $1 | more
# 使用筛选器 'more'
# 也可以用 'less' 替代
exit $? # 脚本的退出状态由管道 pipe 的退出状态决定。
# 实际上 "exit $?" 不一定要写出来,
#+ 因为无论如何脚本都会返回最后执行命令的退出状态。
[[ condition1 && condition2 ]]
if [ "$expr1" -a "$expr2" ]
then
echo "Both expr1 and expr2 are true."
else
echo "Either expr1 or expr2 is false."
fi
[ 1 -eq 1 ] && [ -n "`echo true 1>&2`" ] # 真
[ 1 -eq 2 ] && [ -n "`echo true 1>&2`" ] # 没有输出
# ^^^^^^^ 条件为假。到这里为止,一切都按预期执行。
# 但是
[ 1 -eq 2 -a -n "`echo true 1>&2`" ] # 真
# ^^^^^^^ 条件为假。但是为什么结果为真?
# 是因为括号内的两个条件子句都执行了么?
[[ 1 -eq 2 && -n "`echo true 1>&2`" ]] # 没有输出
# 并不是。
# 所以显然 && 和 || 具备“短路”机制,
#+ 例如对于 &&,若第一个表达式为假,则不执行第二个表达式直接返回假,
#+ 而 -a 和 -o 则不是。