系列文章目录
目录
条件测试
条件测试语句用来测试指定的条件表达式是真还是假。当条件为真是返回0,反之返回非0值。这与一般的编程语言相反,请大家注意。
条件测试的语法有两种:分别是 test命令 和 [命令。
test expression
[ expression ]
其中参数expression是条件表达式,可由字符串、数字、文件名,以及各种运算符组成。
[命令与test命令一样,也是对后面的条件表达式进行测试,但是为了增加程序可读性,Shell要求在条件表达式的右边添加一个右方括号]来与前面[命令配对,
注意expression和 [,]之间都有一个空格!因为"左方括号"也是一条shell命令,命令和参数之间必须有空格。
字符串测试
对于字符串的判断主要是判断是否为空,是否相等。用户可以通过下表列出的5种运算符进行操作
运算符 | 说明 |
---|---|
string | 判断指定的字符串是否为空,不为空返回0 |
string1 = string2 | 判断两个字符串是否相等,相等返回0 |
string1 != string2 | 判断两个字符串是否不相等,不相等返回0 |
-n string | 判断string是否为非空串,非空返回0 |
-z string | 判断string是否为空串,空串返回0 |
对于上表的第一个运算符,只能使用test命令来测试,其余4种,两种测试方式都支持。
在进行字符串比较时,用引号将字符串界定起来是一个非常好的习惯。
#!/bin/bash
a="abc"
b=""
test $a
#非空返回0
echo $?
test $b
#空返回非0
echo $?
test -n $a
#非空返回0
echo $?
test -z $a
#非空返回非0
echo $?
[ -n $a ]
#非空返回0
echo $?
[ -z $a ]
#非空返回非0
echo $?
test "$a" = "$b"
#不相等返回非0
echo $?
[ "$a" != "$b" ]
#不相等返回0
echo $?
结果如下:
eden_ubuntu@edenubuntu:~/Documents/Shell$ ./4-1.sh
0
1
0
1
0
1
1
0
注意:字符串比较是区分大小写的。
这里的 = 和 != 都是运算符,在使用的时候,前后都需要加空格,切记。
整数测试
整数测试的两种语法和字符串类似:
test number1 op number2
[ number1 op number2]
number1和number2表示参与比较的整数,可以是常量和变量,op表示运算符。下表列出常用的整数运算符:
运算符 | 说明 |
---|---|
num1 -eq num2 | 判断两个数是否相等,相等返回0 |
num1 -ne num2 | 判断两个数是否不相等,不相等返回0 |
num1 -gt num2 | 判断num1是否大于num2,大于返回0 |
num1 -lt num2 | 判断num1是否小于num2,小于返回0 |
num1 -ge num2 | 判断num1是否大于等于num2,大于等于返回0 |
num1 -le num2 | 判断num1是否小于等于num2,小于等于返回0 |
实例:
#!/bin/bash
a=12
b=14
[ "$a" -eq "$b"]
#不相等返回非0
echo $?
test "$a" -ne "$b"
#不相等返回0
echo $?
[ "$a" -eq 12 ]
#相等返回0
echo $?
[ "$a" -gt "$b" ]
#不大于返回非0
echo $?
[ "$a" -lt "$b" ]
#小于返回0
echo $?
[ "$a" -ge "12" ]
#大于等于返回0
echo $?
结果:
eden_ubuntu@edenubuntu:~/Documents/Shell$ ./4-2.sh
1
0
0
1
0
0
如果[]之间没有空格,提供将会报错,比如我]前不加空格,系统提示缺失 ] 符号:
./4-2.sh: line 5: [: missing `]'
文件测试
Shell提供了许多与文件有关的操作符来对文件进行检测。如下表:
操作符 | 说明 |
---|---|
-a file | 判断文件是否存在,存在返回0 |
-b file | 判断文件是否存在并且文件类型为块文件,是返回0 |
-c file | 判断文件是否存在并且文件类型为字符文件,是返回0 |
-d file | 判断文件是否存在并且文件类型为目录,是返回0 |
-e file | 效果与-a相同 |
-f file | 判断文件是否存在并且为常规文件,是返回0 |
-s file | 判断file是否是一个非空文件,是返回0 |
-w file | 判断文件是否存在并且文件可写,是返回0 |
-r file | 判断文件是否存在并且文件可读,是返回0 |
-x file | 判断文件是否存在并且文件可执行,是返回0 |
-L file | 判断文件是否存在并且文件是一个符号链接,是返回0 |
-u file | 判断文件是否存在并且是否设置了suid位,是返回0 |
主要检测3方面:文件是否存在;文件的类型;文件的访问权限。
首先在一个目录下创建目录和一些文件,情况如下所示:
eden_ubuntu@edenubuntu:~/Documents/Shell/4-3$ ll
total 16
drwxrwxr-x 3 eden_ubuntu eden_ubuntu 4096 Jul 26 00:26 ./
drwxrwxr-x 3 eden_ubuntu eden_ubuntu 4096 Jul 26 00:18 ../
-rw-rw-r-- 1 eden_ubuntu eden_ubuntu 0 Jul 26 00:26 file1
-rw-rw-r-- 1 eden_ubuntu eden_ubuntu 3 Jul 26 00:27 file2
lrwxrwxrwx 1 eden_ubuntu eden_ubuntu 9 Jul 26 00:19 shortcut.sh -> ../4-2.sh*
drwxrwxr-x 2 eden_ubuntu eden_ubuntu 4096 Jul 26 00:18 tmpDir/
执行测试实例:
#!/bin/bash
test -d tmpDir
echo $?
test -f file1
#file1存在且为普通文件
echo $?
test -s file1
#file1大小为0,返回非0
echo $?
test -s file2
#file1存在且file1大小大于0,返回0
echo $?
test -L shortcut.sh
#shortcut.sh存在且为符号链接,返回0
echo $?
test -b file1
#file1不是块文件,返回非0
echo $?
test -b /dev/sda
#/dev/sda存在且/dev/sda是块文件,返回0
echo $?
test -c /dev/tty
#控制终端/dev/tty存在且/dev/tty是字符文件,返回0
echo $?
结果:
eden_ubuntu@edenubuntu:~/Documents/Shell/4-3$ ./4-3.sh
0
0
1
0
0
1
0
0
逻辑操作符
在Shell编程中,经常会遇到判断多个条件的情况,将多个条件组合成一个条件进行判断,用到 非、或和与的逻辑。看下表
操作符 | 说明 |
---|---|
! expression | 逻辑非 |
expression1 -a expression2 | 逻辑与 |
expression1 -o expression2 | 逻辑或 |
举个简单例子:
#!/bin/bash
a=35
test "$a" -gt 30 -a "$a" -lt 40
echo $?
结果如下:
eden_ubuntu@edenubuntu:~/Documents/Shell$ ./4-4.sh
0
条件判断句
条件判断句使得程序可以根据不同的条件来执行不同的程序分支,主要就是if语句,if else语句,if elif语句,下面列出各种语句的例子。
if 语句
语法为:
if expression
then
statement1
statement2
...
fi
为了使得代码更加紧凑,我们可以让if子句和then子句放在一行,这时候需要在expression表达式后加一个;号
if expression; then
statement1 statement2 ...
fi
或者
if expression; then statement1 statement2 ...; fi
示例如下:
#!/bin/bash
if [ -f ./4-5.sh ]
then
echo "./4-5.sh is a file"
fi
if test -f ./4-5.sh
then echo "./4-5.sh is a file"
fi
if [ -f ./4-5.sh ]; then echo "./4-5.sh is a file"; fi
if :; then echo "always ture"; fi
可以看到if后面可以用 test命令,也可以用[命令
结果为:
eden_ubuntu@edenubuntu:~/Documents/Shell$ ./4-5.sh
./4-5.sh is a file
./4-5.sh is a file
./4-5.sh is a file
always ture
在Shell中还有一个特殊的命令,称为空命令,其表示方法是一个冒号:,改命令不做任何事情,但是它的退出状态永远是0,就是永远为真,在上述例子中我们有展示。
还有的人喜欢用&&操作符代替if语句,如下面的例子:
#!/bin/bash
test -f './4-5.sh' && echo './4-5.sh is a file'
! test -f './4-5-.sh' && echo './4-5.sh is not a file'; exit 1
结果:
eden_ubuntu@edenubuntu:~/Documents/Shell$ ./4-6.sh
./4-5.sh is a file
./4-5.sh is not a file
if else语句
语法为:
if expression
then
statement1
statement2
...
else
statement3
statement4
...
fi
if elif语句
语法为:
if expression1
then
statement1
statement2
...
elif expression2
then
statement3
statement4
...
...
else
statementn
fi
上面两个语句就不多讲了,和其他语言类似的,知道if的用法,这两个是类似的。
多条件判断语句case
类似于C++,java的是switch语句,语法如下:
case variable in
value1)
statement1
...
statementn
;;
value1)
statement1
...
statementn
;;
value1)
statement1
...
statementn
;;
*)
statement1
...
statementn
;;
esac
其中*)就是default选项,当其他分支都没有进去的时候会进入这个分支。
case语句结构以esac结尾,和if语句以fi结构一样,都是以命令名倒序作为命令结尾。
运算符
除了前面列出的一些运算符外,还有一些与数值有关的运算符,比如算术运算符、位运算符、自增/减运算符等。首先我们看看算术运算符,和其他编程语言差不多
算术运算符
运算符 | 说明 |
---|---|
+ | 求两数之和 |
- | 求2数之差 |
* | 求2数之乘积 |
/ | 求2数之商 |
% | 求余/取模 |
** | 幂运算,这个特殊一点,举例:3**4就是3的4次幂 |
下面看下复合算术运算符,这个和C语言中的是一样的,不做过多解释
运算符 | 说明 |
---|---|
+= | 求和后,再将和赋值给左边的变量 |
-= | 求差值后,再将和赋值给左边的变量 |
*= | 求乘积后,再将和赋值给左边的变量 |
/= | 求商后,再将和赋值给左边的变量 |
%/ | 取余后,再将和赋值给左边的变量 |
位运算符
Shell编程也支持位运算符,用法和C语言一样,但是可能用的比较少,下面我们看表
运算符 | |
---|---|
<< | 左移 |
>> | 右移 |
& | 按位与 |
| | 按位或 |
~ | 按位非 |
^ | 按位异或 |
位运算符也有复合运算符
运算符 | |
---|---|
>>= | 左移后将值赋值给左边的变量 |
<<= | 右移后将值赋值给左边的变量 |
&= | 按位与后将值赋值给左边的变量 |
|= | 按位或后将值赋值给左边的变量 |
^= | 按位异或后将值赋值给左边的变量 |
自增/减运算符
用法与C语言一样
运算符 | 说明 |
---|---|
++variable | 先将variable的值加1,然后再赋值给variable |
--variable | 先将variable的值减1,然后再赋值给variable |
variable++ | 先使用variable的值,然后再将variable的值加1 |
variable-- | 先使用variable的值,然后再将variable的值减1 |
执行算术运算
在Shell中有4种方式执行算术运算,分别如下:
使用$((expression))
使用这种形式进行算术运算写法比较自由,无需对运算符和括号做转义处理,可以采用松散或者紧凑的格式来书写表达式。举例:
#!/bin/bash
#采用紧凑格式
result=$((3+7))
echo "$result"
#采用松散格式
result=$(( 3 - 7 ))
echo "$result"
result=$((3*7))
echo "$result"
result=$((8/3))
echo "$result"
result=$((8%3))
echo "$result"
result=$((2**3))
echo "$result"
#复合运算
result=$(((3+7)*2))
echo "$result"
结果:
eden_ubuntu@edenubuntu:~/Documents/Shell$ ./4-7.sh
10
-4
21
2
28
20
使用$[expression]
这个使用方法与$((expression))基本相同,举例:
#!/bin/bash
#采用紧凑格式
result=$[3+7]
echo "$result"
#采用松散格式
result=$[ 3 - 7 ]
echo "$result"
result=$[3*7]
echo "$result"
result=$[8/3]
echo "$result"
result=$[8%3]
echo "$result"
result=$[2**3]
echo "$result"
#复合运算
result=$[(3+7)*2]
echo "$result"
结果与上面一致。
eden_ubuntu@edenubuntu:~/Documents/Shell$ ./4-8.sh
10
-4
21
2
2
20
[]与(()) 的差别在于[]里面不能进行赋值操作,而(())里面支持赋值操作,这个差别可以在后面的 数值常量的进制的例子中看到,大家有兴趣也可以试试。
使用expr命令
expr是一个Shell命令,使用语法:
expr expression
它使用起来有比较多的讲究,不大好用。在使用运算符时,需要对运算符进行转义,如果有括号,也需要对括号进行转义。不能使用紧凑格式,要使用松散格式,举例:
#!/bin/bash
result=`expr 2 + 100`
echo "$result"
result=`expr 2 - 100`
echo "$result"
result=`expr 2 \* 100`
echo "$result"
result=`expr 100 / 2`
echo "$result"
result=`expr 100 % 3`
echo "$result"
result=`expr \( 1 + 3 \) \* 5`
echo "$result"
#错误语法
result=`expr 2+5`
echo "$result"
#错误语法
result=`expr 2+5*10`
echo "$result"
#错误语法
result=`expr 2*(2+5)`
echo "$result"
结果:
eden_ubuntu@edenubuntu:~/Documents/Shell$ ./4-9.sh
102
-98
200
50
1
20
2+5
2+5*10
./4-9.sh: command substitution: line 29: syntax error near unexpected token `('
./4-9.sh: command substitution: line 29: `expr 2*(2+5)'
可以看到前面6项都是正常的,到第7项和第8项结果未到预期,不是整数值而是一个表达式 ,第9项报错。所以使用时要注意避免上述的错误。
使用let命令
使用let命令可以执行一个或者多个算术表达式,其中的变量名无需使用$符号。如果表达式中含有空格或者其他特殊字符,需要引用起来。举例:
#!/bin/bash
n=10
let n=n+1
echo "$n"
let n-=1
echo "$n"
let n=n**2
echo "$n"
let n--
echo "$n"
let n**3
echo "$n"
let的表达式最后要有赋值才有效果。 let n**3是不会修改n的值的。
结果如下:
eden_ubuntu@edenubuntu:~/Documents/Shell$ ./4-10.sh
11
10
100
99
99
数字常量的进制
默认情况下,Shell总是以十进制来表示数字。但是用户也可以在Shell中使用其他进制来表示数字,比如二进制,八进制,十六进制。在Shell中,用户可以使用两种语法来表示不同的进制
1.增加前缀:0开头的数字表示0进制,0x开头的数字表示十六进制
2.使用#号:2#1001表示二进制,8#20表示八进制
实例如下:
#!/bin/bash
a=$((2#1000))
((b=8#20))
((c=16#10))
d=$[0x10]
e=$[020]
f=20
((g=0x10))
((h=(1+3)*5))
echo "$a $b $c $d $e $f $g $h"
结果如下:
eden_ubuntu@edenubuntu:~/Documents/Shell$ ./4-11.sh
8 16 16 16 16 20 16 20
小结
本篇主要探讨了条件测试,判断语句,运算符以及运算符的使用方法等