在shell程序中,条件表达式的条件为真时,返回0,如果为假返回为非0。注意这一点是和Java或者C是反的。
条件测试的语法有两种,分别是test命令和[命令。
在绝大部分的shell中,test都是作为一个内部命令出现的,有些shell中,也同时提供了一个相同名称的外部命令,但是,如果在使用test命令进行测试的时候,如果没有提供绝对路径,则使用的都是内部命令。
除了使用test命令之外,[命令也可以进行条件测试,但是[是一个shell命令,而非条件表达式的一部分,而命令和参数之间必须保留一个空格。
运算符 | 说明 |
---|---|
string | 判断指定的字符串是否为空 |
string1 = string2 | 判断两个字符串string1和string2是否相等 |
string1 != string2 | 判断两个字符串string1和string2是否不相等 |
-n string | 判断string是否是非空串 |
-z string | 判断string是否是空串 |
对于表中第一种运算符,也就是单独给定一个字符串的形式,只能使用test命令来测试是否为空串,而不能使用方括号的方式来测试,对于其他4种运算符,都可以使用test命令或者方括号来进行测试。
注意:在给变量赋值的时候,等号“=”左右两边一定不要有空格,否则,shell就会把空格前面的字符串当做shell命令。
初学者经常遇到的一个问题
#! /bin/bash
a="apple"
b="orange"
test "$a"="$b"
echo $?
正常来说,a和b是两个不同的字符串,但是在shell中0表示相等,那么这个就会产生矛盾,这个问题就出现在比较的那一行,在这种情况下shell并不认为其中的等号是一个字符串运算符,而是看成了一个普通字符,依旧是说判断的是某个字符串是否为空,“apple=orange”不为空,所以测试的结果永远为0。将代码修改成如下:
#! /bin/bash
a="apple"
b="orange"
test "$a" = "$b"
echo $?
运算符 | 说明 |
---|---|
number1 -eq number2 | 是否相等,相等为0 |
number1 -ne number2 | 是否不相等,不相等为0 |
number1 -gt number2 | number1是否大于number2,满足为0 |
number1 -lt number2 | number1是否小于number2,满足为0 |
number1 -ge number2 | number1是否大于等于number2,满足为0 |
number1 -le number2 | number1是否小于等于number2,满足为0 |
#! /bin/bash
a=12
b=14
test "$a" -eq "$b"
echo $?
注意: 字符串运算符和整数运算符不可以混用。
shell提供了许多与文件相关的操作符,通过这些操作符,用户可以对文件的状态进行检测。
操作符 | 说明 |
---|---|
-a file | 文件是否存在,存在则为0 |
-b file | 文件是否存在,且为块文件,满足则为0 |
-c file | 文件是否存在,且为字符文件,满足则为0 |
-d file | 文件是否存在,且为目录,满足则为0 |
-e file | 同-a操作符 |
-s file | 文件是否为非空文件,非空文件则为0 |
-f file | 文件存在且为常规文件,则结果为0 |
-w file | 文件存在且可写,则结果为0 |
-L file | 文件存在且为符号链接,则结果为0 |
-u file | 文件是否设置suid位,如果已经设置结果为0 |
-r file | 文件存在并且可读,则结果为0 |
-x file | 文件是存在且可执行,则结果为0 |
文件操作符的主要功能有3个方面,分别是检测文件是否存在、文件的类型和文件的访问权限。文件权限的设置方法chmod,具体参考前面的文章《文件权限设置》。
操作符 | 说明 |
---|---|
!expression | 逻辑非,条件表达式expression的值为假,则该操作符的运算结果为真 |
expression1 -a expression2 | 逻辑与,条件表达式expression1和expression2的值都是真时,整个表达式的值为真 |
expression1 -o expression2 | 逻辑或,条件表达式expression1或者expression2有一个为真,整个表达式为真 |
if expression; then
statement1
statement2
fi
在if语句中,如果使用条件测试,可以使用test命令,也可以使用方括号[]
shell中还有一个特殊的命令,称为空命令,其表示方法是一个冒号“:”,该命令不做任何事情,但是它的退出状态永远是0,因此,如果我们将该命令作为if语句中的条件,则永远执行then子句。
注意: 在使用if语句的时候一定不要忘记fi。
if expression
then
statement1
statement2
...
else
statement3
statement4
...
fi
例子
#! /bin/bash
#输出提示信息
echo "please enter a number:"
#从键盘读取用户输入的数字
read num
#如果用户输入的数字大于10
if [ "$num" -gt 10 ]; then
#输出大于10的提示信息
echo "the number is greater than 10."
#否则
else
#输出小于或者等于10的提示信息
echo "the number is equal to or less than 10."
fi
if expression1
then
statement1
statement2
...
elif expression2
then
statement3
statement4
...
eilf expression3
then
statement5
statement6
...
else
statementn
...
fi
在shell中,有时候需要满足某个条件的时候退出程序,这种情况下,我们可以通过if配合exit语句进行实现,exit语句的基本作用是终止shell程序的执行,并且还可以带一个可选的参数,用来指定程序退出时的状态码。
exit status
其中,status参数表示退出状态,该参数是一个整数值,取值范围时0-255。尽管用户可以在程序中自己设置退出状态码,但是通常情况下每个状态码都有自己特定的含义。
case variable in
value1)
statement1
statement2
...
statementn;;
value2)
statement1
statement2
...
statementn;;
valuen)
statement1
statement2
...
statementn;;
*)
statement1
statement2
...
statementn;;
esac
variable是一个变量,case语句会将该变量的值与value1-valuen中的每一个值相比较,如果和value相等,则执行对应后面的语句,当遇到“;;"符号时,就跳出case语句,执行esac语句后面的语句,如果没有和任何一个值与variable的值相匹配,则执行*后面的一组语句。
注意:
1.对于变量名variable,可以使用双引号,也可以不使用
2.每个case子句中的条件测试部分,都以右括号“)”结束
3.每个case子句都以一对分号“;;”作为结束符。在脚本执行的过程中,当遇到一对分号时,会跳过当前case子句后面的所有的case子句,包括 * 所应对的子句,执行esac子句后面的其他的语句。
4.case语句结构以esac结尾,这与if语句以fi结尾是一样的,都是以前面单词的逆序结尾。
运算符 | 说明 |
---|---|
+ | 求和 |
- | 求差 |
* | 乘积 |
/ | 商 |
% | 求余 |
** | 幂运算 |
1.使用expr外部程序
expr expression
result='expr 2 - 100'
2.使用$((…))
result=$((3+6))
3.使用$[…]
result=$[4+5]
4.使用let命令
let n=n+1
运算符 | 说明 |
---|---|
+= | 3+=5 |
-= | 5-=2 |
*= | 2*=8 |
/= | 6/=3 |
%= | 22/=3 |
基本等同于C
运算符 | 说明 |
---|---|
<< | 左移 |
>> | 右移 |
& | 按位与 |
| | 按位或 |
~ | 按位非 |
^ | 按位异或 |
基本等同于C
基本等同于C
默认情况,shell总是十进制,在shell中有两种语法来表示不同的进制,首先是增加前缀,以0开头的数字表示八进制,以0x开头的数字表示十六进制,第二种语法是使用“#”,例如2#1000表示二进制,8#42表示八进制。