文章目录
- [1. 基本概述](#1. 基本概述)
- [2. test命令](#2. test命令)
-
- [2.1 基本语法](#2.1 基本语法)
- [2.2 实际应用](#2.2 实际应用)
- [2.3 特点说明](#2.3 特点说明)
- [3. 单括号 [ ]](#3. 单括号 [ ])
-
- [3.1 基本语法](#3.1 基本语法)
- [3.2 实际应用](#3.2 实际应用)
- [3.3 重要注意事项](#3.3 重要注意事项)
- [4. 双括号 [[ ]]](#4. 双括号 [[ ]])
-
- [4.1 基本语法](#4.1 基本语法)
- [4.2 优势特性](#4.2 优势特性)
- [4.3 实际应用](#4.3 实际应用)
- [5. 双括号 (( ))](#5. 双括号 (( )))
-
- [5.1 基本语法](#5.1 基本语法)
- [5.2 算术比较运算符表](#5.2 算术比较运算符表)
- [5.3 实际应用](#5.3 实际应用)
- [6. 数值比较详解](#6. 数值比较详解)
-
- [6.1 比较运算符对照表](#6.1 比较运算符对照表)
- [6.2 实际代码示例](#6.2 实际代码示例)
- [7. 字符串比较详解](#7. 字符串比较详解)
-
- [7.1 字符串操作符对照表](#7.1 字符串操作符对照表)
- [7.2 实际应用](#7.2 实际应用)
- [8. 文件测试详解](#8. 文件测试详解)
-
- [8.1 文件测试操作符大全](#8.1 文件测试操作符大全)
- [8.2 实际应用场景](#8.2 实际应用场景)
- [9. 逻辑操作符组合](#9. 逻辑操作符组合)
-
- [9.1 逻辑操作符对照表](#9.1 逻辑操作符对照表)
- [9.2 组合使用示例](#9.2 组合使用示例)
1. 基本概述
Shell条件测试
test命令
单括号[ ]
双括号[[ ]]
双括号(( ))
可移植性好
但功能有限
test的语法糖
需要空格
Bash/Ksh扩展
功能强大
算术运算专用
适合数值比较
2. test命令
2.1 基本语法
bash
test expression
2.2 实际应用
bash
#!/bin/bash
file="/etc/passwd"
if test -f "$file"; then
echo "文件 $file 存在"
fi
# 检查变量是否为空
if test -z "$USER"; then
echo "USER变量为空"
fi
2.3 特点说明
- 最古老的测试方式,所有POSIX兼容shell都支持
- 返回值:条件为真返回0,为假返回1
- 可移植性最佳,但功能相对有限
3. 单括号 [ ]
test命令的语法糖
3.1 基本语法
bash
[ expression ]# 注意:括号内侧必须有空格
3.2 实际应用
bash
#!/bin/bash
count=10name="Alice"
# 数值比较
if [ $count -gt 5 ]; then
echo "count大于5"
fi
# 字符串比较
if [ "$name" = "Alice" ]; then
echo "姓名是Alice"
fi
# 文件测试
if [ -f "/etc/hosts" ]; then
echo "hosts文件存在"
fi
# 组合条件
if [ $count -ge 10 ] && [ "$name" != "Bob" ]; then
echo "条件满足"
fi
3.3 重要注意事项
bash
# ❌ 错误:缺少空格
[$count -gt 5] # 会报错
# ✅ 正确:有空格
[ $count -gt 5 ]
# ❌ 变量未加引号(如果变量为空会出错)
[ $var = "value" ]
# ✅ 变量加引号(安全)
[ "$var" = "value" ]
4. 双括号 [[ ]]
Bash/Ksh增强测试
4.1 基本语法
bash
[[ expression ]]
4.2 优势特性
| 特性 | [[ ]] | [ ] |
|---|---|---|
| 模式匹配 | ✅ 支持 | ❌ 不支持 |
| 正则匹配 | ✅ 支持 | ❌ 不支持 |
| 逻辑操作符 | &&, || | -a, -o |
| 字符串比较 | ==, != | =, != |
| 变量引号 | 可选 | 必需 |
| 词分割 | 不进行 | 进行 |
4.3 实际应用
bash
#!/bin/bash
filename="test.log"
pattern="*.log"
number="123"
path="/usr/local/bin"
# 1. 模式匹配
if [[ "$filename" == *.log ]]; then
echo "这是一个日志文件"
fi
# 2. 正则表达式匹配
if [[ "$number" =~ ^[0-9]+$ ]]; then
echo "这是纯数字"
fi
# 3. 字符串比较(更直观)
if [[ $name == "Alice" ]]; then
echo "Hello Alice"
fi
# 4. 逻辑运算符(更直观)
if [[ -f "$file" && -r "$file" ]]; then
echo "文件存在且可读"
fi
# 5. 路径名扩展检查
if [[ -d "$path" ]]; then
echo "$path 是一个目录"
fi
# 6. 空变量检查(无需引号)
empty_var=""
if [[ -z $empty_var ]]; then
echo "变量为空"
fi
5. 双括号 (( ))
5.1 基本语法
bash
(( arithmetic_expression ))
# 当算术比较的结果非0时返回真(0),结果为0时返回假(1)
5.2 算术比较运算符表
| 运算符 | 描述 | 示例 |
|---|---|---|
| == | 等于 | (( a == b )) |
| != | 不等于 | (( a != b )) |
| < | 小于 | (( a < b )) |
| > | 大于 | (( a > b )) |
| <= | 小于等于 | (( a <= b )) |
| >= | 大于等于 | (( a >= b )) |
| && | 逻辑与 | (( a > 0 && b < 10 )) |
| || | 逻辑或 | (( a == 0 || b == 0 )) |
| ! | 逻辑非 | (( ! (a == b) )) |
5.3 实际应用
bash
#!/bin/bash
a=10
b=20
c=0
# 1. 简单比较
if (( a < b )); then
echo "a小于b"
fi
# 2. 算术运算
if (( a * 2 > b )); then
echo "a的两倍大于b"
fi
# 3. 自增自减
counter=0
while (( counter < 5 )); do
echo "计数: $counter"
(( counter++ )) # 自增
done
# 4. 复杂表达式
if (( (a + b) > 25 && a % 2 == 0 )); then
echo "条件满足"
fi
# 5. 三元运算风格
(( max = a > b ? a : b ))
echo "最大值是: $max"
# 6. 位运算
flags=5 # 二进制 0101
if (( (flags & 1) == 1 )); then
echo "最低位是1"
fi
6. 数值比较详解
6.1 比较运算符对照表
数值比较
test/[ ]用法
(( ))用法
-eq 等于
-ne 不等于
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
== 等于
!= 不等于
> 大于 < 小于
>= 大于等于 <= 小于等于
6.2 实际代码示例
bash
#!/bin/bash
num1=10
num2=20
echo "使用test/[ ]:"
if [ $num1 -lt $num2 ]; then
echo "$num1 小于 $num2"
fi
echo -e "\n使用(( )):"
if (( num1 < num2 )); then
echo "$num1 小于 $num2"
fi
# 浮点数比较(需要bc命令)
float1=3.14
float2=2.71
if [ $(echo "$float1 > $float2" | bc) -eq 1 ]; then
echo "$float1 大于 $float2"
fi
7. 字符串比较详解
7.1 字符串操作符对照表
| 操作符 | test/[ ] | [[ ]] | 说明 |
|---|---|---|---|
| 等于 | = 或 == | = 或 == | [[ ]]中==是标准 |
| 不等于 | != | != | |
| 小于 | < (需转义) | < | 按字典序比较 |
| 大于 | > (需转义) | > | 按字典序比较 |
| 空检查 | -z | -z | 字符串长度为0 |
| 非空检查 | -n | -n | 字符串长度不为0 |
7.2 实际应用
bash
#!/bin/bash
str1="hello"
str2="world"
str3=""
str4="HELLO"
# 1. 基本比较
if [ "$str1" = "hello" ]; then
echo "字符串相等"
fi
# 2. 字典序比较
if [[ "$str1" < "$str2" ]]; then
echo "'$str1' 在 '$str2' 之前"
fi
# 3. 空值检查
if [ -z "$str3" ]; then
echo "str3是空字符串"
fi
if [ -n "$str1" ]; then
echo "str1不是空字符串"
fi
# 4. 大小写敏感比较
if [[ "$str1" == "hello" ]]; then
echo "精确匹配"
fi
# 5. 大小写不敏感比较(Bash 4+)
if [[ "${str1,,}" == "${str4,,}" ]]; then
echo "忽略大小写匹配"
fi
# 6. 包含关系检查
if [[ "$str1" == *"ell"* ]]; then
echo "包含子串'ell'"
fi
# 7. 前缀/后缀检查
if [[ "$str1" == "hel"* ]]; then
echo "以'hel'开头"
fi
if [[ "$str1" == *"lo" ]]; then
echo "以'lo'结尾"
fi
8. 文件测试详解
8.1 文件测试操作符大全
| 操作符 | 描述 | 示例 |
|---|---|---|
| -e | 文件/目录是否存在 | [ -e file ] |
| -f | 是否为普通文件 | [ -f file ] |
| -d | 是否为目录 | [ -d dir ] |
| -L | 是否为符号链接 | [ -L link ] |
| -r | 是否可读 | [ -r file ] |
| -w | 是否可写 | [ -w file ] |
| -x | 是否可执行 | [ -x file ] |
| -s | 文件大小是否>0 | [ -s file ] |
| -O | 文件所有者是否为当前用户 | [ -O file ] |
| -G | 文件所属组是否为当前用户组 | [ -G file ] |
| -N | 文件自上次读取后是否被修改 | [ -N file ] |
| file1 -nt file2 | file1是否比file2新 | [ file1 -nt file2 ] |
| file1 -ot file2 | file1是否比file2旧 | [ file1 -ot file2 ] |
| file1 -ef file2 | 是否相同文件(硬链接) | [ file1 -ef file2 ] |
8.2 实际应用场景
bash
#!/bin/bash
file="/etc/passwd"
dir="/tmp"
link="/usr/bin/python"
# 1. 检查文件存在性
if [[ -e "$file" ]]; then
echo "$file 存在"
fi
# 2. 检查文件类型
if [[ -f "$file" ]]; then
echo "$file 是普通文件"
fi
if [[ -d "$dir" ]]; then
echo "$dir 是目录"
fi
if [[ -L "$link" ]]; then
echo "$link 是符号链接"
fi
# 3. 检查权限
if [[ -r "$file" ]]; then
echo "$file 可读"
fi
if [[ -w "$file" ]]; then
echo "$file 可写"
fi
# 4. 检查文件新旧
log1="/var/log/syslog"
log2="/var/log/auth.log"
if [[ "$log1" -nt "$log2" ]]; then
echo "$log1 比 $log2 新"
fi
# 5. 复合文件检查
backup_file="/backup/data.tar.gz"
if [[ -f "$backup_file" && -s "$backup_file" ]]; then
echo "备份文件存在且非空"
if [[ -r "$backup_file" && -O "$backup_file" ]]; then
echo "并且可读且属于当前用户"
fi
fi
# 6. 检查特殊文件
socket="/var/run/docker.sock"
if [[ -S "$socket" ]]; then
echo "$socket 是socket文件"
fi
named_pipe="/tmp/myfifo"
if [[ -p "$named_pipe" ]]; then
echo "$named_pipe 是命名管道"
fi
9. 逻辑操作符组合
9.1 逻辑操作符对照表
| 逻辑 | test/[ ] | [[ ]] | (( )) | 说明 |
|---|---|---|---|---|
| 与 | -a | && | && | 所有条件为真 |
| 或 | -o | || | || | 任一条件为真 |
| 非 | ! | ! | ! | 条件取反 |
| 分组 | ( ) | ( ) | ( ) | 改变优先级 |
9.2 组合使用示例
bash
#!/bin/bash
age=25
name="John"
file="/tmp/test.txt"
# 1. 基本逻辑组合
# 使用test/[ ]
if [ "$age" -gt 18 -a "$name" = "John" ]; then
echo "John成年了"
fi
# 使用[[ ]]
if [[ $age -gt 18 && $name == "John" ]]; then
echo "John成年了"
fi
# 2. 复杂逻辑组合
score=85
attendance=90
if [[ ($score -ge 60 && $attendance -ge 80) || $score -ge 90 ]]; then
echo "考试通过"
fi
# 3. 使用括号改变优先级
if [[ $age -gt 18 && ($name == "John" || $name == "Jane") ]]; then
echo "成年人John或Jane"
fi
# 4. 文件检查组合
if [[ -f "$file" && ( -r "$file" || -w "$file" ) ]]; then
echo "文件存在且可读或可写"
fi
# 5. 逻辑非的应用
if [[ ! -d "/nonexistent" ]]; then
echo "目录不存在"
fi
if [[ ! ( $age -lt 18 && $name == "Child" ) ]]; then
echo "不是小孩Child"
fi