1、条件测试结构
if/then结构用来判断命令列表的退出状态码是否为0(因为在UNIX惯例, 0表示"成功"), 如果成功的话, 那么就执行接下来的一个或多个命令.
有一个专有命令[ (左中括号, 特殊字符). 这个命令与test命令等价, 并且出于效率上的考虑,这是一个内建命令. 这个命令把它的参数作为比较表达式或者作为文件测试, 并且根据比较的结果来返回一个退出状态码(0 表示真, 1表示假).
在版本2.02的Bash中, 引入了[[ ... ]]扩展测试命令.注意[[是一个关键字, 并不是一个命令.
(( ... ))和let ...结构也能够返回退出状态码, 当它们所测试的算术表达式的结果为非零的时候, 将会返回退出状态码0. 这些算术扩展结构被用来做算术比较.
*if命令能够测试任何命令, 并不仅仅是中括号中的条件.
#/bin/bash if cmp a b &> /dev/null then echo "Files a and b are identical" else echo "Files a and b differ" fi #非常有用的"if-grep"结构: if grep -q Bash file then echo "File contains at least one occurrence of Bash" fi word=linux letter_sequence=inu if echo "$word" | grep -q "$letter_sequence" #-q 用来禁止输出 then echo "$letter_sequence found in $word" else echo "$letter_sequence not found in $word" fi exit 0
如果 if 和then在条件判断的同一行上的话, 必须使用分号来结束 if 表达式. if 和then都是关键字. 关键字(或者命令)如果作为表达式的开头, 并且如果想在同一行上再写一个新的表达式的话, 那么必须使用分号来结束上一句表达式.
if [ -x "$filename" ]; then
Else if和elif
elif
elif 是else if的缩写形式. 作用是在外部的判断结构中再嵌入一个内部的if/then结构.if test condition-true 结构与 if [ condition-true ] 完全相同.就像我们前面所看到的, 左中括号,[ , 是调用test命令的标识. 而关闭条件判断用的的右中括号.
[[ ]]结构比[ ]结构更加通用. 这是一个扩展的test命令
*在[[和]]之间所有的字符都不会发生文件名扩展或者单词分割, 但是会发生参数扩展和命令替换.
(( ))结构扩展并计算一个算术表达式的值. 如果表达式的结果为0, 那么返回的退出状态码为1, 或者是"假". 而一个非零值的表达式所返回的退出状态码将为0, 或者是"true". 这种情况和先前所讨论的test命令和[ ]结构的行为正好相反.
2、文件测试操作符
-e
文件存在
-a
文件存在这个选项的效果与-e相同. 但是它已经被"弃用"了, 并且不鼓励使用.
-f
表示这个文件是一个一般文件(并不是目录或者设备文件)
-s
文件大小不为零
-d
表示这是一个目录
-b
表示这是一个块设备(软盘, 光驱, 等等.)
-c
表示这是一个字符设备(键盘, modem, 声卡, 等等.)
-p
这个文件是一个管道
-h
这是一个符号链接
-L
这是一个符号链接
-S
表示这是一个socket
-t
文件(描述符)被关联到一个终端设备上这个测试选项一般被用来检测脚本中的 stdin ( [ -t 0 ] )或者 stdout ( [ -t 1 ] )是否来自于一个终端.
-r
文件是否具有可读权限( 指的是正在运行这个测试命令的用户是否具有读权限)
-w
文件是否具有可写权限(指的是正在运行这个测试命令的用户是否具有写权限)
-x
文件是否具有可执行权限(指的是正在运行这个测试命令的用户是否具有可执行权限)
-g
set-group-id(sgid)标记被设置到文件或目录上如果目录具有 sgid 标记的话, 那么在这个目录下所创建的文件将属于拥有这个目录的用户组, 而不必是创建这个文件的用户组. 这个特性对于在一个工作组中共享目录非常有用.
-u
set-user-id (suid)标记被设置到文件上
-k
设置 粘贴位
-O
判断你是否是文件的拥有者
-G
文件的group-id是否与你的相同
-N
从文件上一次被读取到现在为止, 文件是否被修改过
f1 -nt f2
文件 f1 比文件 f2 新
f1 -ot f2
文件 f1 比文件 f2 旧
f1 -ef f2
文件 f1 和文件 f2 是相同文件的硬链接
!
"非" -- 反转上边所有测试的结果(如果没给出条件, 那么返回真).
3、其他比较操作符
-eq
等于if [ "$a" -eq "$b" ]
-ne
不等于if [ "$a" -ne "$b" }
-gt
大于if [ "$a" -gt "$b" }
-ge
大于等于if [ "$a" -ge "$b" }
-lt
小于if [ "$a" -lt "$b" }
-le
小于等于if [ "$a" -le "$b" }
<
小于(在双括号中使用)(("$a" < "$b"))
<=
小于等于(在双括号中使用)(("$a" <= "$b"))
>
大于(在双括号中使用)(("$a" > "$b"))
>=
大于等于(在双括号中使用)(("$a" >= "$b"))
字符串比较
=
等于if [ "$a" = "$b" ]
==
等于if [ "$a" == "$b" ] #与=等价
!=
不等于if [ "$a" != "$b" ]
<
小于, 按照ASCII字符进行排序if [[ "$a" < "$b" ]] if [ "$a" \< "$b" ]
注意 “<”在使用[ ]结构中的时候需要 转义
>
大于, 按照ASCII字符进行排序if [[ "$a" > "$b" ]] if [ "$a" \> "$b" ]
注意 “<”在使用[ ]结构中的时候需要 转义
-z
字符串为"null", 意思就是字符串长度为零
-n
字符串不为"null".
compound comparison
-a
逻辑与
exp1 -a exp2如果表达式exp1和exp2都为真的话, 那么结果为真.
-o
逻辑或
exp1 -o exp2如果表达式exp1和exp2中至少有一个为真的话, 那么结果为真.
这与Bash中的比较操作符&&和||非常相像, 但是这个两个操作符是用在 双中括号结构中的.[[ condition1 && condition2 ]] [[ condition1 || condition2 ]]
-o和-a操作符一般都是和test命令或者是单中括号结构一起使用的.if [ "exp1" -a "exp2" ]
4、嵌套的if/then条件测试
可以通过if/then结构来使用嵌套的条件测试.if [ condition1 ] then if [ condition2 ] then do something # But only if both "condition1" and "conditon2" valid. fi fi