0%

判断语句

Shell 中的判断语句:test、[] 与 [[]] 的全面用法

在 Shell 脚本中,判断语句是实现条件逻辑的基础。无论是文件类型检查、权限验证,还是数值 / 字符串比较,都需要通过判断语句实现。本文详细讲解 test 命令、[ ][[ ]] 三种判断方式的用法及差异。

判断语句的三种形式

Shell 中常用的判断形式有三种,功能类似但语法略有差异:

形式 说明 兼容性
test 条件 基础判断命令 所有 Shell 兼容
[ 条件 ] test 命令的简化写法(注意空格) 所有 Shell 兼容
[[ 条件 ]] Bash 扩展语法,支持更多特性 仅 Bash、Zsh 等现代 Shell 支持

基本用法示例

三种形式可以互换,结果完全一致:

1
2
3
4
# 判断文件是否为目录
test -d /etc && echo "是目录" || echo "不是目录"
[ -d /etc ] && echo "是目录" || echo "不是目录"
[[ -d /etc ]] && echo "是目录" || echo "不是目录"

输出均为是目录

文件类型判断

用于检查文件是否存在及类型(目录、普通文件等),常用选项如下:

选项 含义 示例
-e 文件 文件或目录是否存在 [ -e /etc/passwd ] → 检查密码文件是否存在
-d 目录 是否为目录且存在 [ -d /tmp ] → 检查 /tmp 是否为目录
-f 文件 是否为普通文件且存在 [ -f ~/.bashrc ] → 检查用户配置文件是否为普通文件
-s 文件 文件是否存在且非空(大小 > 0) [ -s log.txt ] → 检查日志文件是否有内容
-L 链接 是否为符号链接 [ -L /usr/bin/python ] → 检查 Python 命令是否为软链接
-b 设备 是否为块设备(如硬盘) [ -b /dev/sda ] → 检查第一块硬盘
-c 设备 是否为字符设备(如键盘) [ -c /dev/tty0 ] → 检查终端设备

示例:检查文件状态并输出信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
file="data.txt"

if [ -e "$file" ]; then
echo "$file 存在"
if [ -f "$file" ]; then
echo "$file 是普通文件"
if [ -s "$file" ]; then
echo "$file 非空"
else
echo "$file 为空文件"
fi
else
echo "$file 不是普通文件"
fi
else
echo "$file 不存在"
fi

文件权限判断

检查文件是否拥有读、写、执行权限:

选项 含义 示例
-r 文件 是否有读权限 [ -r /etc/shadow ] → 普通用户通常返回 false
-w 文件 是否有写权限 [ -w ~/test.txt ] → 检查用户目录下文件是否可写
-x 文件 是否有执行权限 [ -x /usr/bin/ls ] → 检查 ls 命令是否可执行

示例:检查脚本是否可执行,若不可执行则添加权限

1
2
3
4
5
6
7
8
9
10
script="deploy.sh"

if [ -f "$script" ]; then
if [ ! -x "$script" ]; then # "!" 表示取反
echo "添加执行权限..."
chmod +x "$script"
else
echo "$script 已可执行"
fi
fi

数值比较

用于整数之间的比较(不支持浮点数):

选项 含义 示例
-eq 等于(equal) [ 10 -eq 10 ] → true
-ne 不等于(not equal) [ 10 -ne 20 ] → true
-gt 大于(greater than) [ 20 -gt 10 ] → true
-lt 小于(less than) [ 5 -lt 10 ] → true
-ge 大于等于(greater or equal) [ 10 -ge 10 ] → true
-le 小于等于(less or equal) [ 5 -le 10 ] → true

示例:比较两个数字大小

1
2
3
4
5
6
7
8
9
10
11
a=15
b=20

if [ $a -gt $b ]; then
echo "$a 大于 $b"
elif [ $a -lt $b ]; then
echo "$a 小于 $b"
else
echo "$a 等于 $b"
fi
# 输出:15 小于 20

字符串比较

用于字符串的 equality、空值等判断:

选项 含义 示例
= 或 == 字符串相等(==[[ ]] 推荐) [ "abc" = "abc" ] → true
!= 字符串不等 [ "abc" != "def" ] → true
-z 字符串 字符串长度为 0(空字符串) [ -z "" ] → true
-n 字符串 字符串长度不为 0(非空) [ -n "hello" ] → true

示例:检查用户输入是否为空

1
2
3
4
5
6
7
read -p "请输入姓名:" name

if [ -z "$name" ]; then # 注意变量用双引号包裹,避免空值导致语法错误
echo "姓名不能为空!"
else
echo "你好,$name!"
fi

逻辑组合判断

多个条件的与、或、非组合:

逻辑 test/[ ] 写法 [[ ]] 写法 说明
条件1 -a 条件2 条件1 && 条件2 两个条件都为真才成立
条件1 -o 条件2 ` 条件 1 条件 2` 至少一个条件为真
! 条件 ! 条件 条件为假时成立

示例:多条件组合判断

1
2
3
4
5
6
7
8
9
# 使用 [ ] 组合条件(-a 表示与)
if [ -f "file.txt" -a -r "file.txt" ]; then
echo "file.txt 是可读的普通文件"
fi

# 使用 [[ ]] 组合条件(&& 表示与)
if [[ -f "file.txt" && -r "file.txt" ]]; then
echo "file.txt 是可读的普通文件"
fi

[[ ]] 的高级特性

[[ ]] 是 Bash 扩展语法,支持更多便捷功能:

字符串包含判断

无需借助 grep,直接用通配符 * 匹配:

1
2
3
4
5
6
7
str="hello world"

# 判断 str 是否包含 "world"
if [[ $str == *world* ]]; then
echo "包含 'world'"
fi
# 输出:包含 'world'

正则表达式匹配

使用 =~ 支持正则匹配:

1
2
3
4
5
6
7
8
email="test@example.com"

# 简单验证邮箱格式
if [[ $email =~ ^[a-zA-Z0-9_]+@[a-zA-Z0-9]+\.[a-zA-Z]+$ ]]; then
echo "邮箱格式正确"
else
echo "邮箱格式错误"
fi

无需转义特殊字符

[[ ]] 中特殊字符(如 *?)无需转义,直接使用:

1
2
3
4
5
# 判断文件名是否以 .sh 结尾
file="script.sh"
if [[ $file == *.sh ]]; then # * 无需转义
echo "$file 是 Shell 脚本"
fi

常见错误与注意事项

  1. 空格问题
    • [ 条件 ][[ 条件 ]] 中,[/[[ 后、]/]] 前必须有空格,如 [ -f file ] 正确,[-f file] 错误。
  2. 变量引用
    • 字符串变量和可能为空的变量必须用双引号包裹,避免语法错误:
      [ "$name" = "root" ] 正确,[ $name = "root" ] 可能报错(若 name 为空)。
  3. 兼容性
    • [[ ]] 是 Bash 扩展,若脚本需在 sh 等兼容 Shell 中运行,应使用 [ ]
  4. 数值与字符串混淆
    • 数值比较用 -eq/-gt 等,字符串比较用 =/!=,不可混用。

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10