一、语法格式
shell 中的 if 语句的格式如下:
if 条件; then
command1
else
command2
fi
或者将 then 单独另起一行也可以,这时条件后面的 ; 便可以去掉:
if 条件
then
command1
else
command2
fi
google 规范推荐使用第一种,即:将 ; do , ; then 和 while , for , if 放在同一行。
比如:
if [[ $a == $b ]]; then
echo "equal"
fi
二、判断条件
if 的判断条件如何写,这里面大有文章。
1、空格的使用
shell脚本对空格有严格的规定:
- 赋值语句中等号
=两边不能有空格,而字符串比较中等号=、==两边必须有空格。 - 中括号
[]、[[]]前后一定要加空格。
$ i=1 # =用作赋值时,两边绝对不能有空格
$ if [ $a = $b ] # =、==等用作比较判断时,两边必须有空格;中括号前后一定要加空格。
2、不同括号的区别
在if条件中常见的括号有三种:(())、[]、[[]],区别如下:
(1)(())只能进行整数比较,不能用于字符串比较,括号中的变量可以省略$符号前缀,当然也可以带着。
(2)[]和[[]]的区别:
- 本质上,
[]和test是等价的,都是命令,而[[]]是关键字,所以重定向等字符在[]中会被认为成重定向,而在[[]]中是比较符号的意思。 &&、||、<和>操作符能够正常存在于[[]]条件判断结构中,但是如果出现在[]结构中的话,会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不使用双括号, 则为if [ $a != 1] && [ $a != 2 ]或者if [ $a != 1 -a $a != 2 ][[]]支持字符串的模式匹配,[]不支持。使用=或==进行字符串比较,等号右边的可以作为一个模式,比如[[ "hello" == hell? ]]为真。模式匹配不能加引号,否则会作为固定字符串,如[[ "hello" == "hell?" ]]为假。[[]]支持算术扩展,而[]不支持。如if [[ 1+2 -eq 3 ]],而if [ 1+2 -eq 3 ]则会报错。
3、比较运算符
在shell中对比字符串和对比数字,是要分开两种方式:
字符串对比
对比字符串只能使用=、==、<、>、!=、-z、-n。其中,-n 表示字符串不为空,即长度大于0,-z 表示字符串为空,即长度为0。
备注:
- 使用
[]对比字符串时,末尾一定要加上x(或者a、b等)一个字符,因为[ $ax == "ab"x ]如果没有了x,并且$a是"",这个语句会翻译成if [ == "ab" ],左边相当于没有东西了,会报语法错误。或者使用[[ ]],就不需要x了。 - 使用
<或者>时,如果是用[],需要用转义\,如\>。 - 使用
-z-n时,如果是用[],则字符串一定要加双引号(单引号都不行),如:[ -n "$a" ];如果是用[[]],则加不加双引号都可以(但一定不能加单引号)。
数字对比
对比数字,只能使用==、=、!=,或者 -eq、-ne、-gt、-ge、-lt、-le。其中-eq的意思是 equal,-ne是 unequal,-gt是 greater than,-ge是 greater than or equal to,-lt是 less than,-le是 less than or equal to。
备注:
- 在
[][[]]中,数字对比不支持><<=和>=,比如[[ 1 -gt -1 ]]为真,但[[ 1 > -1 ]]为假。 - 在
(())中,数字对比是支持><<=和>=的,但不支持-eq、-ne、-gt、-ge、-lt、-le等。这是因为括号内只要符合C语言规则的运算符都可以。
=与==的区别(字符串和数字均适用):
1、在[ ]或[[]]中,=与==表示判断,是等价的
2、在·(( ))中,=表示赋值,==表示判断,它们不等价
4、逻辑运算符
and可以用-a 或 &&表示,or可以用-o或||表示。它们在[]和[[]]是不同的:
[[]]只能使用&&||,不能使用-a``-o。&&``||写在括号里或外都可以。(())与[[]]相同,只不过可以省略变量前的$,且只能用于整数比较。[]既可以使用&&||,也可以使用-a``-o。但&&``||必须在括号外,-a``-o必须在括号内。
即:
| 括号内连接 | 括号外连接 | |
|---|---|---|
[] | -a -o | && || |
[[]] | && || | && || |
比如a=3 ; b=2 ; c=4,要判断是否a>b且a<c,有以下几种正确的写法:
if (( a > b )) && (( a < c )) # 正确
if (( a > b && a < c )) # 正确
if [[ $a -gt $b ]] && [[ $a -lt $c ]] # 正确
if [[ $a -gt $b && $a -lt $c ]] # 正确
if [ $a -gt $b ] && [ $a -lt $c ] # 正确
if [ $a -gt $b -a $a -lt $c ] # 正确
5、文件判断
可以在if中进行文件状态的判断,常用的包括:
-
-e文件是否存在 -
-d表示文件是否是目录 -
-f文件是否是普通文件(不是目录、设备文件、链接文件) -
-s表示文件大小不为0 -
-b表示是块设备(光驱、软盘等) -
-c表示是字符设备(键盘、声卡等) -
-p表示是管道 -
-h表示是符号链接 -
-S表示是否是socket -
-r、-w、-x表示文件是否有可读、可写、可执行权限(指运行这个测试命令的用户) -
f1 -nt f2f1是否比f2新(new than) -
f1 -ot f2f1是否比f2旧(old than) -
f1 -ef f2f1和f2是否是相同文件的硬链接
使用!时表示上述结果取反,比如:
myfile="test.txt"
if [ ! -e $myfile ]; then
echo $myfile" is not exist"
touch $myfile
else
echo $myfile" is exist"
fi
本文介绍了shell中if语句的语法格式,google规范推荐将相关内容放在同一行。还详细阐述了判断条件,包括空格使用规则、不同括号区别、字符串和数字的比较运算符、逻辑运算符,以及文件状态判断等,如文件是否存在、是否为目录等。
33万+





