Shell 脚本通常需要测试if 命令是否成功或条件是否满足。在 Bash 中,这种测试可以通过 Bash if 语句 来完成。与任何其他编程语言一样,Bash 带有 条件表达式,允许你测试条件并根据条件是否满足来改变控制流。
本文介绍 bash if 语句 及其相关子句 then、else if(elif)和 else。
Bash If 语句简介
在编程中,if 语句 是一种条件语句,也称为条件表达式。if 语句 在给定条件满足时执行一部分代码。它通常被称为 If-Then、If-Else 或 If-Then-Else 语句。if 语句 总是测试一个布尔条件以评估为 true 或 false。then、else if(elif)和 else 是 if 语句 的子句。
Bash If 语句的语法是什么?
在 Bash 中,if 语句 是编程语言的 条件结构 的一部分。Bash 脚本中的 if 是一个 shell 关键字,用于根据测试命令的退出状态来测试条件。退出状态为零(且仅为零)表示成功,即条件为 真。任何其他退出状态表示失败,即条件为 假。
Bash 中 if 语句 的语法为:
if first-test-commands; then
consequent-commands;
[elif more-test-commands; then
more-consequents;]
[else alternate-consequents;]
fi
bash if 语句和 bash elif 子句中的测试命令按顺序执行,直到某个测试成功。如果没有测试成功,并且提供了 bash else 子句,则执行最终 else 子句中的代码部分。
双圆括号 ((…))、单方括号 […] 和双方括号 [[…]] 是什么?
((...))、[...] 和 [[...]] 结构通常用于使用比较运算符评估复杂的条件表达式,并返回退出状态 0 或 1,以便在 bash if 语句 中使用。
双圆括号 ((...)) 用于测试算术表达式。你可以在我们的博文 bash 算术 中了解更多关于此结构的信息。它支持 && 和 || 二元运算符。
单方括号 [...] 是命令 [,它是一个 shell 内置命令,也是 test 命令的别名。test 命令和别名 [ 用于评估条件表达式。这是 POSIX 标准的一部分。
双方括号与单方括号表示法之间有一些显著差异:
- 双方括号执行模式匹配,右侧可以是一个 glob 模式。注意,如果右侧字符串被引用,globbing 将不起作用。
- 双方括号表示法防止单词拆分,因此你可以省略字符串变量周围的引号。
- 双方括号表示法不展开文件名。
- 双方括号表示法支持
&&和||二元运算符。 - 双方括号表示法在使用
=~表示法时支持正则表达式模式匹配。
双方括号 [[...]] 是一个 shell 关键字。它在行为上与单方括号类似,用于评估条件表达式,并且是 Bash、Zsh 和 Korn shell 特有的。此结构可以处理更复杂的条件,并且更不容易出错,请参阅常见问题解答中关于 单括号命令错误使用 的一些示例。
注意,((...)) 和 [[...]] 结构是 Bash 复合命令。
Bash 条件表达式有哪些?
条件表达式由 [[ 复合命令以及 test 和 [ 内置命令使用。条件表达式可以是单目(一个操作数)或双目(两个操作数)。单目运算符通常用于测试文件、变量、shell 选项(optname)或字符串的状态。
单目和双目表达式由以下 基本元素 构成。
| 条件表达式 | 含义 |
|---|---|
| -a file | 如果 file 存在则为真。 |
| -b file | 如果 file 存在且是块特殊文件则为真。 |
| -c file | 如果 file 存在且是字符特殊文件则为真。 |
| -d file | 如果 file 存在且是目录则为真。 |
| -e file | 如果 file 存在则为真。 |
| -f file | 如果 file 存在且是常规文件则为真。 |
| -g file | 如果 file 存在且设置了 set-group-id 位则为真。 |
| -h file | 如果 file 存在且是符号链接则为真。 |
| -k file | 如果 file 存在且设置了“粘滞”位则为真。 |
| -p file | 如果 file 存在且是命名管道(FIFO)则为真。 |
| -r file | 如果 file 存在且可读则为真。 |
| -s file | 如果 file 存在且大小大于零则为真。 |
| -t fd | 如果文件描述符 fd 打开且指向终端则为真。 |
| -u file | 如果 file 存在且设置了 set-user-id 位则为真。 |
| -w file | 如果 file 存在且可写则为真。 |
| -x file | 如果 file 存在且可执行为真。 |
| -G file | 如果 file 存在且属于有效组 ID 则为真。 |
| -L file | 如果 file 存在且是符号链接则为真。 |
| -N file | 如果 file 存在且自上次读取后已被修改则为真。 |
| -O file | 如果 file 存在且属于有效用户 ID 则为真。 |
| -S file | 如果 file 存在且是套接字则为真。 |
| file1 -ef file2 | 如果 file1 和 file2 引用相同的设备和 inode 编号则为真。 |
| file1 -nt file2 | 如果 file1 比 file2 更新(根据修改日期),或者 file1 存在而 file2 不存在则为真。 |
| file1 -ot file2 | 如果 file1 比 file2 更旧,或者 file2 存在而 file1 不存在则为真。 |
| -o optname | 如果 shell 选项 optname 已启用则为真(参见 set -o 获取选项列表)。 |
| -v varname | 如果 shell 变量 varname 已设置(已被赋值,即使为空值)则为真。 |
| -R varname | 如果 shell 变量 varname 已设置且是名称引用则为真。 |
| -z string | 如果 string 的长度为零则为真。 |
| -n string | 如果 string 的长度非零则为真。 |
| string1 == string2 string1 = string2 | 如果字符串相等则为真。当与 [[ 命令一起使用时,将执行模式匹配。= 表示法应与 test 命令一起使用以符合 POSIX。 |
| string1 != string2 | 如果 字符串 不相等则为真。 |
| string1 =~ regex | 如果 字符串 匹配 Bash 正则表达式 regex 则为真。捕获的组存储在 BASH_REMATCH 数组变量 中。 |
| string1 < string2 | 如果 string1 在字典顺序上排在 string2 之前则为真。 |
| string1 > string2 | 如果 string1 在字典顺序上排在 string2 之后则为真。 |
条件表达式还支持如下算术二元运算符,其中 arg1 和 arg2 是正负整数。当与 [[ 命令一起使用时,arg1 和 arg2 被评估为算术表达式,因此应优先使用 (( 复合命令。
| 条件表达式 | 含义 |
|---|---|
| arg1 -eq arg2 | 如果 arg1 等于 arg2 则为真 |
| arg1 -ne arg2 | 如果 arg1 不等于 arg2 则为真 |
| arg1 -lt arg2 | 如果 arg1 小于 arg2 则为真 |
| arg1 -le arg2 | 如果 arg1 小于或等于 arg2 则为真 |
| arg1 -gt arg2 | 如果 arg1 大于 arg2 则为真 |
| arg1 -ge arg2 | 如果 arg1 大于或等于 arg2 则为真 |
如何使用带有 Then、Else、Else If(elif)子句的 If 语句?
如前所述,If 语句 必须有一个 then 子句,并且可以选择包含一个带有关键字 elif 后跟 then 的 else if 子句,和/或一个 else 子句。If 语句 总是以关键字 fi 结尾。
if、then、else、elif 和 fi 关键字必须是一行的最后一个关键字,或者在任何其他关键字使用之前需要用分号 ; 终止。
if false; then
echo '此命令永远不会运行,因为条件始终为假。';
elif ((RANDOM%2)); then
echo '只有当 $RANDOM % 2 等于 0 时,此命令才会执行。';
else
echo '如果没有其他条件满足,则执行此命令。';
fi
将 Bash If 语句与条件表达式一起使用
注意,条件不需要任何特殊的括起字符(如圆括号),尽管它们可能用于覆盖其他运算符的优先级。根据要执行的测试,可以直接使用命令,或者使用 [[ 复合命令,或者 test 和 [ 内置命令。(( 复合命令保留用于算术扩展。关键字和命令之间的空格很重要。
例如,如果我们要测试文件是否存在且是常规文件(不是符号链接),我们可以使用 -f 基本元素,采用以下任何表示法。
[me@linux ~]$ touch myfile
[me@linux ~]$ if [[ -f myfile ]]; then echo "myfile exists. If Statement Condition equal $?."; fi
myfile exists. If Statement Condition equal 0.
[me@linux ~]$ if [ -f myfile ]; then echo "myfile exists. If Statement Condition equal $?."; fi
myfile exists. If Statement Condition equal 0.
[me@linux ~]$ if test -f myfile; then echo "myfile exists. If Statement Condition equal $?."; fi
myfile exists. If Statement Condition equal 0.
你可以使用 ! 关键字否定条件。
[me@linux ~]$ rm myfile
[me@linux ~]$ if [[ ! -f myfile ]]; then echo "myfile does not exist. If Statement Condition equal $?."; fi
myfile does not exist. If Statement Condition equal 0.
将 Bash If 语句与多个条件一起使用
如上所述,你可以在双方括号 [[ 复合表示法中使用二元运算符 &&(与)和 ||(或)。这类似于在单括号中使用 -a(与)和 -o(或)。
[me@linux ~]$ touch myfile
[me@linux ~]$ if [[ -f myfile && -r myfile ]]; then echo "File exists and is Readable."; fi
File exists and is Readable.
[me@linux ~

1058

被折叠的 条评论
为什么被折叠?



