Shell系统学习之Shell条件测试,判断语句和运算符

系列文章目录

Shell系统学习之什么是Shell

Shell系统学习之创建一个Shell程序

Shell系统学习之向Shell脚本传递参数

Shell系统学习之如何执行Shell程序

Shell系统学习之Shell变量和引用

 Shell系统学习之Shell条件测试,判断语句和运算符

 Shell系统学习之循环结构

 Shell系统学习之函数

Shell系统学习之数组

系统学习Shell之正则表达式

Shell系统学习之文件操作

Shell系统学习之子Shell与进程处理


目录

条件测试

字符串测试

整数测试

文件测试

逻辑操作符 

条件判断句

if 语句

 if else语句

if elif语句

多条件判断语句case

运算符

算术运算符

位运算符

自增/减运算符

执行算术运算

使用$((expression))

使用$[expression]

使用expr命令

使用let命令

数字常量的进制 

 小结


条件测试

条件测试语句用来测试指定的条件表达式是真还是假。当条件为真是返回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
2

8
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

 小结

本篇主要探讨了条件测试,判断语句,运算符以及运算符的使用方法等

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值