条件语句

跟其它程序设计语言一样,Bash中的条件语句让我们可以决定一个操作是否被执行。结果取决于一个包在[[ ]]里的表达式。

条件表达式可以包含&&||运算符,分别对应 。除此之外还有很多有用的表达式

共有两个不同的条件表达式:ifcase

基元和组合表达式

[[ ]]sh中是[ ])包起来的表达式被称作 检测命令基元。这些表达式帮助我们检测一个条件的结果。在下面的表里,为了兼容sh,我们用的是[ ]。这里可以找到有关bash中单双中括号区别的答案。

跟文件系统相关:

基元 含义
[ -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 ] FILE1FILE2新(newer than)
[ FILE1 -ot FILE2 ] FILE1FILE2旧(older than)

跟字符串相关:

基元 含义
[ -z STR ] STR为空(长度为0,zero)
[ -n STR ] STR非空(长度非0,non-zero)
[ STR1 == STR2 ] STR1STR2相等
[ STR1 != STR2 ] STR1STR2不等

算数二元运算符:

基元 含义
[ ARG1 -eq ARG2 ] ARG1ARG2相等(equal)
[ ARG1 -ne ARG2 ] ARG1ARG2不等(not equal)
[ ARG1 -lt ARG2 ] ARG1小于ARG2less than)
[ ARG1 -le ARG2 ] ARG1小于等于ARG2less than or equal)
[ ARG1 -gt ARG2 ] ARG1大于ARG2greater than)
[ ARG1 -ge ARG2 ] ARG1大于等于ARG2greater than or equal)

条件语句可以跟 组合表达式 配合使用:

Operation Effect
[ ! EXPR ] 如果EXPR为假,为真
[ (EXPR) ] 返回EXPR的值
[ EXPR1 -a EXPR2 ] 逻辑 , 如果EXPR1和(and)EXPR2都为真,为真
[ EXPR1 -o EXPR2 ] 逻辑 , 如果EXPR1或(or)EXPR2为真,为真

当然,还有很多有用的基元,在Bash的man页面能很容易找到它们。

使用if

if在使用上跟其它语言相同。如果中括号里的表达式为真,那么thenfi之间的代码会被执行。fi标志着条件代码块的结束。

  1. # 写成一行
  2. if [[ 1 -eq 1 ]]; then echo "true"; fi
  3. # 写成多行
  4. if [[ 1 -eq 1 ]]; then
  5. echo "true"
  6. fi

同样,我们可以使用if..else语句,例如:

  1. # 写成一行
  2. if [[ 2 -ne 1 ]]; then echo "true"; else echo "false"; fi
  3. # 写成多行
  4. if [[ 2 -ne 1 ]]; then
  5. echo "true"
  6. else
  7. echo "false"
  8. fi

有些时候,if..else不能满足我们的要求。别忘了if..elif..else,使用起来也很方便。

看下面的例子:

  1. if [[ `uname` == "Adam" ]]; then
  2. echo "Do not eat an apple!"
  3. elif [[ `uname` == "Eva" ]]; then
  4. echo "Do not take an apple!"
  5. else
  6. echo "Apples are delicious!"
  7. fi

使用case

如果你需要面对很多情况,分别要采取不同的措施,那么使用case会比嵌套的if更有用。使用case来解决复杂的条件判断,看起来像下面这样:

  1. case "$extension" in
  2. "jpg"|"jpeg")
  3. echo "It's image with jpeg extension."
  4. ;;
  5. "png")
  6. echo "It's image with png extension."
  7. ;;
  8. "gif")
  9. echo "Oh, it's a giphy!"
  10. ;;
  11. *)
  12. echo "Woops! It's not image!"
  13. ;;
  14. esac

每种情况都是匹配了某个模式的表达式。|用来分割多个模式,)用来结束一个模式序列。第一个匹配上的模式对应的命令将会被执行。*代表任何不匹配以上给定模式的模式。命令块儿之间要用;;分隔。