跳至内容

Bash - 条件结构 if 和 case


目标:在本章中,您将学会如何

✔ 使用 `if` 条件语法;
✔ 使用 `case` 条件语法;

🏁 **linux**,**script**,**bash**,**conditional structures**

知识⭐ ⭐
复杂性: ⭐ ⭐ ⭐

阅读时间: 20 分钟


条件结构

如果使用 `$?` 变量来了解测试或命令执行的结果,它只能被显示,而不会影响脚本的执行。

但是我们可以用它来做条件判断。**如果** 测试成功 **那么** 我执行此操作 **否则** 我执行另一个操作。

`if` 条件替代结构的语法

if command
then
    command if $?=0
else
    command if $?!=0
fi

`if` 关键字后面的命令可以是任何命令,因为它将评估该命令的返回码(`$?`)。通常使用 `test` 命令来定义多个依赖于测试结果的操作(文件是否存在、变量是否为空、是否有写入权限)会很方便。

使用经典命令(`mkdir`、`tar` 等)允许你定义成功时要执行的操作,或失败时要显示的错误消息。

示例

if [[ -e /etc/passwd ]]
then
    echo "The file exists"
else
    echo "The file does not exist"
fi

if mkdir rep
then
    cd rep
fi

如果 `else` 块以一个新的 `if` 结构开头,你可以将 `else` 和 `if` 合并为 `elif`,如下所示:

[...]
else
  if [[ -e /etc/ ]]
[...]

[...]
# is equivalent to
elif [[ -e /etc ]]
[...]

总结

`if` / `then` / `else` / `fi` 结构评估 `if` 后面的命令。

  • 如果该命令的返回码为 `0`(`true`),shell 将执行 `then` 之后放置的命令;
  • 如果返回码不等于 `0`(`false`),shell 将执行 `else` 之后放置的命令。

`else` 块是可选的。

通常需要仅在命令评估为 true 时执行某些操作,而在 false 时不做任何操作。

`fi` 关键字用于关闭该结构。

当 `then` 块中只有一个命令要执行时,可以使用更简单的语法。

如果 `$?` 为 `true` 要执行的命令放在 `&&` 之后,而如果 `$?` 为 `false` 要执行的命令放在 `||`(可选)之后。

示例

[[ -e /etc/passwd ]] && echo "The file exists" || echo "The file does not exist"
mkdir dir && echo "The directory is created".

还可以通过比 `if` 更简洁的结构来评估和替换变量。

此语法实现了花括号

  • 如果变量为空,则显示替换值

    ${variable:-value}
    
  • 如果变量不为空,则显示替换值

    ${variable:+value}
    
  • 如果变量为空,则为其赋新值

    ${variable:=value}
    

示例

name=""
echo ${name:-linux}
linux
echo $name

echo ${name:=linux}
linux
echo $name
linux
echo ${name:+tux}
tux
echo $name
linux

提示

在决定使用 `if`、`then`、`else`、`fi` 或上述更简单的语法示例时,请牢记脚本的可读性。如果脚本只有你自己使用,那么你可以使用最适合你的方式。如果其他人可能需要审查、调试或跟踪你创建的脚本,请使用更具自我说明性的形式(`if`、`then` 等),或者确保你的脚本有详细的文档,以便其他人能够理解并修改和使用该脚本。无论如何,为脚本编写文档始终是一件好事,正如这些课程中前面多次提到的那样。

替代条件:`case` 结构

一系列 `if` 结构可能会很快变得笨重和复杂。当涉及对同一变量的评估时,可以使用具有多个分支的条件结构。变量的值可以指定,也可以属于可能性列表。

可以使用通配符.

`case ... in` / `esac` 结构评估 `case` 关键字后面的变量,并将其与定义的值进行比较。

在找到第一个匹配项时,将执行 `)` 和 `;;` 之间的命令。

被评估的变量和提出的值可以是字符串或命令子执行的结果。

在结构末尾放置的 `*` 选择表示要为所有先前未测试过的值执行的操作。

`case` 替代条件的语法

case $variable in
  value1)
    commands if $variable = value1
    ;;
  value2)
    commands if $variable = value2
    ;;
  [..]
  *)
    commands for all values of $variable != of value1 and value2
    ;;
esac

当值可能变化时,建议使用通配符 `[]` 来指定可能性。

[Yy][Ee][Ss])
  echo "yes"
  ;;

字符 `|` 也允许你指定一个值或另一个值。

"yes" | "YES")
  echo "yes"
  ;;

作者:Antoine Le Morvan

贡献者:Steven Spencer, Ganna Zhyrnova