跟其它程序设计语言一样,Bash中的条件语句让我们可以决定一个操作是否被执行。结果取决于一个包在[[ ]]
(sh
中是[ ]
)里的表达式。[[ ]]
包起来的表达式被称作 检测命令 或 基元。
条件表达式可以包含&&
和||
运算符,分别对应 与 和 或 。共有两个不同的条件表达式:if
和case
。
跟文件系统相关:
基元 | 含义 |
---|---|
[ -e FILE ] | 如果FILE 存在 (exists),为真 |
[ -f FILE ] | 如果FILE 存在且为一个普通文件(file),为真 |
[ -d FILE ] | 如果FILE 存在且为一个目录(directory),为真 |
[ -s FILE ] | 如果FILE 存在且非空(size 大于0),为真 |
[ -r FILE ] | 如果FILE 存在且有读权限(readable),为真 |
[ -w FILE ] | 如果FILE 存在且有写权限(writable),为真 |
[ -x FILE ] | 如果FILE 存在且有可执行权限(executable),为真 |
[ -L FILE ] | 如果FILE 存在且为一个符号链接(link),为真 |
[ FILE1 -nt FILE2 ] | FILE1 比FILE2 新(newer than) |
[ FILE1 -ot FILE2 ] | FILE1 比FILE2 旧(older than) |
跟字符串相关:
基元 | 含义 |
---|---|
[ -z STR ] | STR 为空(长度为0,zero) |
[ -n STR ] | STR 非空(长度非0,non-zero) |
[ STR1 == STR2 ] | STR1 和STR2 相等 |
[ STR1 != STR2 ] | STR1 和STR2 不等 |
算数二元运算符:
基元 | 含义 |
---|---|
[ ARG1 -eq ARG2 ] | ARG1 和ARG2 相等(equal) |
[ ARG1 -ne ARG2 ] | ARG1 和ARG2 不等(not equal) |
[ ARG1 -lt ARG2 ] | ARG1 小于ARG2 (less than) |
[ ARG1 -le ARG2 ] | ARG1 小于等于ARG2 (less than or equal) |
[ ARG1 -gt ARG2 ] | ARG1 大于ARG2 (greater than) |
[ ARG1 -ge ARG2 ] | ARG1 大于等于ARG2 (greater than or equal) |
条件语句可以跟 组合表达式 配合使用:
Operation | Effect |
---|---|
[ ! EXPR ] | 如果EXPR 为假,为真 |
[ (EXPR) ] | 返回EXPR 的值 |
[ EXPR1 -a EXPR2 ] | 逻辑 与, 如果EXPR1 和(and)EXPR2 都为真,为真 |
[ EXPR1 -o EXPR2 ] | 逻辑 或, 如果EXPR1 或(or)EXPR2 为真,为真 |
1. if语句
# 1. 一个分支
NUM=3
if [[ ${NUM} -eq 3 ]]; then
echo "true"
fi
# 2. 两个分支
if [[ ${NUM} -ne 1 ]]; then
echo "true"
else
echo "false"
fi
# 3.多个分支
NAME="MIKE"
if [[ ${NAME} == "mike" ]]; then
echo "It's mike!"
elif [[ ${NAME} == "MIKE" ]]; then
echo "It's mike!"
else
echo "wrong name!"
fi
2. case 语句
- 在
case
命令后面跟着的参数是被匹配的模式,这里用$1
来获取执行脚本时传入的第一个参数。在in
参数跟着可以处理的模式列表,每一项用)
作为结尾。 - 可以用
2 | 3 | 4)
这样的形式来匹配多个模式,每个模式用|
隔开。如果写为1) | 2) | 3)
的形式会报错。即,只有最后一个模式才用)
来结尾。 - 模式列表不限于数字,可以是不带引号的字符串、带引号的字符串、bash 的扩展语句、通配符,等等。例如上面使用了
$var
来匹配 var 变量的值。 - 如果要匹配的字符串带有空格,一定要用引号括起来,否则会报错。
- 可以使用
*
通配符来表示匹配任意内容,类似于默认分支语句,这个语句一定要写在最后面,否则会先匹配到它,影响它后面语句的匹配。 - 每个模式处理完之后,一定要用
;;
、;&
、或者;;&
来结尾。如果这三个都没有提供则会报错。 ;;
表示不再往下匹配,会结束整个case
命令的执行。作用类似于在select
中执行break
命令。;&
表示继续执行下面一个模式里面的语句,不检查下一个模式是否匹配。上面的"big lion")
模式使用了;&
结尾,从执行结果可以看到,它会往下执行"fall through from big lion")
模式的语句。;;&
表示继续往下匹配,如果找到匹配的模式,则执行该模式里面的语句。上面的2 | 3 | 4)
模式使用了;;&
结尾,当匹配到 2 时,它继续往下匹配,中间没有找到匹配项,一直到*)
才匹配,执行了*)
模式里面的语句。当匹配到 4 时,往下匹配到了$var)
模式,然后$var)
模式里面用;;
结束执行,没有再往下匹配。
case ${panel} in
exon)
echo "got subpan";;
subpan)
echo "got subpan";;
pan)
echo "got pan";;
*)
echo "wrong panel";;
esac
# 联合getopts命令
while getopts "bf" arg; do
case ${arg} in
b) handle_option_b ;;
f) handle_option_f ;;
?) show_help ;;
esac
done