Shell:条件判断
在Shell脚本中,条件判断是非常基础且重要的功能,它允许脚本根据条件的不同执行不同的代码块。Shell提供了多种方式来进行条件判断,包括if
语句、case
语句以及使用测试命令(如[ ]
、[[ ]]
、test
等)进行条件测试。
1. if语句
if
语句是Shell脚本中最常用的条件判断语句。它的基本语法如下:
|
|
注意:[ ]
中的条件判断表达式两边需要有空格。
2. 条件判断表达式
条件判断表达式可以使用多种测试命令和操作符来组合,以下是一些常见的例子:
-
数值比较:
-eq
(等于)、-ne
(不等于)、-gt
(大于)、-ge
(大于等于)、-lt
(小于)、-le
(小于等于)。 -
字符串比较:
=
(等于,注意与-eq
的区别,这里是字符串比较)、!=
(不等于)、<
(小于,在[[ ]]
中使用时需要转义或双引号包围)、>
(大于,同上)。=
和-eq
的区别- 在
[ ]
条件表达式中,通常使用=
进行字符串比较(尽管这实际上是赋值操作符的语法,但在[ ]
中有特殊含义)。 - 在bash的
[[ ]]
条件表达式中,可以使用==
进行字符串比较,以提高代码的可读性。 - 对于数值比较,应该使用
-eq
、-ne
等专门的数值比较操作符。
- 在
-
文件测试:
-e
(文件存在)、-f
(文件存在且为常规文件)、-d
(文件存在且为目录)、-r
(文件存在且可读)、-w
(文件存在且可写)、-x
(文件存在且可执行)。
3. 示例
数值比较
|
|
字符串比较
|
|
注意:在字符串比较时,推荐使用双引号将变量包围起来,以防止变量为空或包含空格时导致的问题。
文件测试
|
|
检查用户是否为 root
|
|
4. [[ ]]与 [ ]的区别
[[ ]]
是bash的扩展功能,提供了更多的灵活性和功能(如模式匹配),并且在使用时不需要对变量和字符串值进行引号包围(尽管这样做仍然是一个好习惯)。[ ]
是POSIX标准测试命令,更加通用,但在某些情况下可能需要更多的引号来避免错误。
在编写可移植的Shell脚本时,建议优先考虑使用[ ]
,除非你需要[[ ]]
提供的特定功能。
5. case语句
case
语句是另一种条件判断的方式,它允许脚本根据变量的值匹配多个模式,并执行相应的命令块。
|
|
在这个例子中,case
语句检查变量var
的值,并根据其值匹配相应的模式。如果找到匹配的模式,则执行该模式下的命令块。*
是一个通配符,用于捕获所有不匹配前面任何模式的值。
6. 逻辑运算符
在Shell脚本中,逻辑运算符用于组合条件表达式,以形成更复杂的条件判断。主要的逻辑运算符包括:
&&
(AND):逻辑与运算符。当两边的操作数都为真时,整个表达式才为真。||
(OR):逻辑或运算符。当两边的操作数中至少有一个为真时,整个表达式为真。!
(NOT):逻辑非运算符。用于取反一个操作数的真假值。
这些逻辑运算符通常在if
语句中与其他测试表达式一起使用,以决定执行哪条路径。在Bash中,你可以使用[
和]
或[[
和]]
来构建这些条件表达式。
示例:使用&&
和||
|
|
示例:使用!
运算符
|
|
在上述例子中:
&&
运算符确保var1
和var2
都非空时,才输出相应的信息。||
运算符则检查var1
或var2
是否至少有一个为空。!
运算符用于检查文件$file
是否不存在。
需要注意的是,&&
和||
运算符具有短路评估的特性,这意味着一旦左侧的条件足以确定整个表达式的真假,右侧的条件就不会被评估。例如,在A && B
中,如果A
为假,则不会评估B
,因为此时整个表达式必然为假。
示例:实现运算符?:
可以使用逻辑运算符&&
和||
在Bash中实现一种类似于C语言中的条件(三元)运算符?:
的功能。这种技巧利用了逻辑运算符的短路评估特性。下面是如何在Bash中使用&&
和||
来模拟?:
运算符的示例:
|
|
在这个示例中:
[ "$condition" = true ]
是一个测试表达式,如果$condition
等于字符串true
,则返回真(0退出状态)。&&
是一个逻辑与运算符,它在左侧的表达式为真时才会评估右侧的表达式。||
是一个逻辑或运算符,它在左侧的表达式为假时才会评估右侧的表达式。
由于&&
和||
的短路评估特性,当[ "$condition" = true ]
为真时,echo "$val_if_true"
会被执行,否则echo "$val_if_false"
会被执行。$( ... )
命令替换语法用于捕获输出并将结果赋值给result
变量。
这种方法虽然不像C语言中的?:
运算符那样简洁,但在Bash中提供了一种有效的方法来基于条件选择不同的值。然而,在更复杂的逻辑或更长的代码段中,使用传统的if
语句可能会使代码更易于阅读和维护。