test
是 Shell 脚本中用于条件判断的关键命令,它通过返回 退出状态码(0 表示条件成立,非 0 表示不成立)来控制程序流程。以下是详细的讲解:
1. 基本语法
test EXPRESSION # 标准形式
[ EXPRESSION ] # 方括号等价于 test,注意空格!
-
空格要求:
[
和]
必须与表达式之间有空格,否则会报错。[ -e file.txt ] # 正确 [-e file.txt] # 错误
2. 文件测试操作符
用于检查文件或目录的状态:
操作符 | 说明 | 示例 |
---|---|---|
-e | 文件存在 | test -e file.txt |
-f | 是普通文件(非目录) | [ -f /etc/passwd ] |
-d | 是目录 | [ -d /tmp ] |
-r | 可读 | [ -r file.txt ] |
-w | 可写 | [ -w file.txt ] |
-x | 可执行 | [ -x script.sh ] |
-s | 文件大小 > 0 | [ -s empty.txt ] |
-L | 符号链接 | [ -L symlink ] |
示例:
if [ -f /etc/hosts ]; then
echo "文件存在"
else
echo "文件不存在"
fi
3. 数值比较操作符
仅适用于整数比较(不支持浮点数):
操作符 | 说明 | 示例 |
---|---|---|
-eq | 等于 | test 5 -eq 5 |
-ne | 不等于 | [ 10 -ne 5 ] |
-gt | 大于 | [ 5 -gt 3 ] |
-lt | 小于 | [ 2 -lt 4 ] |
-ge | 大于等于 | [ 5 -ge 5 ] |
-le | 小于等于 | [ 3 -le 5 ] |
注意:不能直接写 5 > 3
,必须用 -gt
。
4. 字符串比较操作符
操作符 | 说明 | 示例 |
---|---|---|
= 或 == | 相等 | [ "$a" = "hello" ] |
!= | 不等 | [ "$a" != "world" ] |
-z | 字符串为空(长度为0) | [ -z "$str" ] |
-n | 字符串非空 | [ -n "$str" ] |
注意:
- 使用
=
或==
时,建议用双引号包裹变量(防止空值或空格问题)。 ==
是 Bash 扩展,标准用法推荐=
。
5. 逻辑操作符
操作符 | 说明 | 示例 |
---|---|---|
-a | 逻辑与(AND) | [ -f file.txt -a -r file.txt ] |
-o | 逻辑或(OR) | [ -f file.txt -o -d file.txt ] |
! | 逻辑非(NOT) | [ ! -f file.txt ] |
注意:-a
和 -o
的优先级低于 !
6. 退出状态码
- 0:条件成立(True)
- 非 0:条件不成立(False)
示例:
if [ 5 -eq 5 ]; then
echo "条件成立"
else
echo "条件不成立"
fi
7. [[ ]] 和 (( ))
-
[[ ... ]]
:条件测试结构[[ ... ]]
是 Bash 中的 增强型条件测试结构,用于字符串比较、模式匹配、逻辑判断等操作。它比传统的[ ... ]
(test 命令)更强大,功能更丰富。-
支持字符串比较:
-
使用
==
、!=
进行字符串比较。 -
支持通配符(
*
、?
)和正则表达式(=~
)。 -
示例:
if [[ "hello" == "he*" ]]; then echo "Pattern matches" fi
-
-
逻辑操作符:
-
使用
&&
(与)、||
(或)组合条件。 -
示例:
if [[ "$var" -gt 10 && "$var" -lt 20 ]]; then echo "var is between 10 and 20" fi
-
-
正则表达式匹配:
-
使用
=~
操作符匹配正则表达式。 -
示例:
if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then echo "Valid email format" fi
-
-
安全性:
[[ ... ]]
不会进行文件名扩展(globbing),避免意外匹配文件路径。- 变量中的空格或特殊字符不需要额外转义(但仍建议用引号包裹)。
-
兼容性:
[[ ... ]]
是 Bash 的扩展特性,不兼容 POSIX 标准(如sh
)。
-
示例代码
#!/bin/bash # 字符串比较 str="example.txt" if [[ "$str" == "*.txt" ]]; then echo "File is a .txt file" fi # 正则表达式匹配 if [[ "$str" =~ \.txt$ ]]; then echo "Matches .txt pattern" fi # 逻辑组合 num=15 if [[ "$num" -gt 10 && "$num" -lt 20 ]]; then echo "Number is in range" fi
-
-
(( ... ))
:算术运算和比较(( ... ))
是 Bash 中的 算术运算和比较结构,专门用于整数运算和比较操作。它简化了数学表达式的书写。-
算术运算:
-
支持
+
、-
、*
、/
、%
等运算符。 -
示例:
(( result = 5 + 3 * 2 )) echo $result # 输出 11
-
-
整数比较:
-
使用
<
、>
、<=
、>=
、==
、!=
进行比较。 -
示例:
if (( 5 > 3 )); then echo "5 is greater than 3" fi
-
-
变量引用:
-
在
(( ... ))
中,变量名前不需要$
符号。 -
示例:
a=10 (( a += 5 )) # a = 15
-
-
返回值:
-
如果表达式结果为非零,则返回状态码 0(成功);结果为零时返回状态码 1(失败)。
-
示例:
if (( 5 == 5 )); then echo "Condition is true" fi
-
-
示例代码
#!/bin/bash # 算术运算 a=5 b=3 (( c = a * b )) echo "Result of multiplication: $c" # 输出 15 # 整数比较 x=10 if (( x % 2 == 0 )); then echo "$x is even" else echo "$x is odd" fi # 逻辑判断 y=20 if (( y > 10 && y < 30 )); then echo "$y is between 10 and 30" fi
-
-
使用建议
-
使用
[[ ... ]]
的场景:- 需要字符串比较、模式匹配或正则表达式。
- 需要组合多个逻辑条件(如
&&
、||
)。 - 脚本需要更高的可读性和安全性。
-
使用
(( ... ))
的场景:- 需要执行算术运算或整数比较。
- 需要简洁地操作变量(无需
$
符号)。 - 脚本需要处理数学表达式。
-
-
注意事项
-
[[ ... ]]
与[ ... ]
的区别:[ ... ]
是 POSIX 标准的test
命令,兼容性更好,但功能较弱。[[ ... ]]
是 Bash 的扩展,功能更强大(如支持=~
和&&
)。
-
(( ... ))
与[ ... ]
的区别:[ ... ]
无法直接处理数学运算,需使用-eq
、-gt
等操作符。(( ... ))
专为数学运算设计,语法更简洁。
-
避免混淆:
- 不要在
[ ... ]
或test
中使用&&
、||
等逻辑操作符(会导致语法错误)。 - 在
[[ ... ]]
中可以安全使用这些操作符。
- 不要在
-
8. 常见错误与注意事项
-
空格问题:
[ $var = "value" ] # 错误:如果 var 为空,变成 [ = "value" ] [ "$var" = "value" ] # 正确:用双引号包裹变量
-
文件名含空格:
file="my file.txt" [ -f "$file" ] # 正确:用双引号包裹变量
-
优先使用
[[ ... ]]
:[[ ... ]]
是 Bash 的扩展,支持更安全的语法(如==
、模式匹配)。- 例如:
[[ "$str" == h* ]]
匹配以 h 开头的字符串。
9. 实际应用场景
检查文件是否存在并读取:
if [ -f "data.txt" ]; then
cat data.txt
else
echo "文件不存在"
fi
数值比较:
read -p "输入年龄: " age
if [ "$age" -ge 18 ]; then
echo "成年人"
else
echo "未成年人"
fi
字符串比较:
read -p "输入密码: " pass
if [ "$pass" = "123456" ]; then
echo "登录成功"
else
echo "密码错误"
fi
10. 总结
test
是 Shell 条件判断的基础工具,但语法严格(需注意空格和引号)。- 推荐使用
[[ ... ]]
替代[ ... ]
,以获得更安全、灵活的语法。 - 实际开发中,优先处理变量时使用双引号,避免因空值或空格导致错误。
通过合理使用 test
或 [[ ... ]]
,可以高效控制 Shell 脚本的流程逻辑!
👍 不要在该奋斗的年纪选择安逸
😊 希望对你有帮助!