xDroid's Blog

20.5 Shell 条件表达式 (从新手到菜鸟的Linux教程)

除了 js 和 c/cpp 的三目操作符 [] ? [] : [] 和 python 的 [val1] if [cond] else [val2] 是的我就是要吐槽它们顺序不一样 ,应该大部分语言的条件表达式只有 if-else 类或者 switch-case 类,那么我们也从这两种看一下 bash 里怎么做条件判断。

if-else

基本语法是

if [ cond1 ]
then
  exp1
elif [ cond2 ]
  exp2
else
  exp3
fi

假设大家都已经掌握了 if-else 结构,这里只强调几个不按常理出牌的地方:

  • 左右方括号周围要有空格,不然就是语法错误(原因接下来说道 test 的时候会分析),比如:
      $ if [ 1 -ne 2 ]; then echo "Surely"; else echo "Math taught by literature teacher."; fi
      Surely
      $ if [1 -ne 2 ]; then echo "Surely"; else echo "Math taught by literature teacher."; fi
      bash: [1: command not found
      Math taught by literature teacher.
      $ if [ 1 -ne 2]; then echo "Surely"; else echo "Math taught by literature teacher."; fi
      bash: [: missing `]'
      Math taught by literature teacher.
    这里我们也展示了如何将 if-else 写在同一行内。
  • 和 matlab 不一样的地方是, if-else 块用 fi 结束,而不是 end (相比之下我觉得还是 matlab 的写法好一点)。
  • 测试条件是返回值等于 0 为真,返回值非零为假(真 TM 奇怪,居然和 VB 差不多

[ 与 test

上面提到了左右方括号两边必须加空格,这是为什么呢?

$ help [
[: [ arg... ]
    Evaluate conditional expression.
    
    This is a synonym for the "test" builtin, but the last argument must
    be a literal `]', to match the opening `['.

这就很有趣了,我们再来看看 test 的帮助:

$ help test
test: test [expr]
    Evaluate conditional expression.
    
    Exits with a status of 0 (true) or 1 (false) depending on
    the evaluation of EXPR.  Expressions may be unary or binary.  Unary
    expressions are often used to examine the status of a file.  There
    are string operators and numeric comparison operators as well.
    
    The behavior of test depends on the number of arguments.  Read the
    bash manual page for the complete specification.

因此 [ 只是 test 的别名,只是最后一个参数必须是 ] ;至于 test 能干嘛,只要知道它测试文件状态、比较字符串或数字就可以了——剩下的,文档都说了 Read the bash manual page for the complete specification 面向 StackOverFlow 编程就可以了

if-else 的简化写法

我们注意到既然条件表达式可以包含命令,那么我们就可以直接把分支中的表达式“接”在做出判断后面;这种技巧是这样实现的:

condition && if_succeed || if_failed

这种语句为什么能够成立留作习题

case-esac 结构

是的,他们又把单词反过来了(手动微笑),举个例子:

$ day="Sat"
$ case $day in
>   Mon | Tue | Wed | Thu | Fri)
>     echo 'Oh no, we have to work today.'
>     ;;
>   Sat | Sun)
>     echo 'Relax!'
>     ;;
>   *)
>     echo 'Sorry aliens.'
>     ;;
> esac
Relax!

别忘了打两个分号。