Shell脚本之 “[]“ 详解

[ ] 是 Shell 中用于条件测试的重要结构(也称为 test 命令)。它是 Shell 脚本中进行条件判断的基础工具,虽然看起来简单,但功能非常丰富。

基本概念

  1. [ 实际上是一个命令(通常是 /usr/bin/[ 或 shell 内置命令)
  2. ][ 命令必需的最后一个参数
  3. 命令格式:[ 表达式 ]
  4. 表达式结果为真时返回 0,假时返回 1

基本语法

if [ 条件 ]; then
    # 条件为真时执行的命令
fi

1. 文件测试

操作符说明
-e 文件文件是否存在
-f 文件是普通文件(非目录/设备文件)
-d 文件是目录
-s 文件文件大小不为空
-r 文件文件可读
-w 文件文件可写
-x 文件文件可执行
-L 文件是符号链接
-O 文件文件属于当前用户
-G 文件文件属于当前用户的组
-N 文件文件自上次读取后被修改过
文件1 -nt 文件2文件1比文件2新
文件1 -ot 文件2文件1比文件2旧

示例

if [ -f "/etc/passwd" ]; then
    echo "是一个普通文件"
fi

if [ ! -d "/tmp" ]; then
    echo "/tmp 不是目录"
fi

2. 字符串比较

操作符说明
-z "字符串"字符串长度为0
-n "字符串"字符串长度不为0
"串1" = "串2"字符串相等
"串1" != "串2"字符串不相等
"串1" < "串2"串1在字典序中小于串2
"串1" > "串2"串1在字典序中大于串2

注意

  • 字符串比较操作符两侧必须有空格
  • 使用 <> 时需要转义(或放在 [[ ]] 中)

示例

if [ "$USER" = "root" ]; then
    echo "你是root用户"
fi

if [ -n "$PATH" ]; then
    echo "PATH不为空"
fi

3. 数值比较

操作符说明
num1 -eq num2等于 (equal)
num1 -ne num2不等于 (not equal)
num1 -gt num2大于 (greater than)
num1 -ge num2大于等于 (greater or equal)
num1 -lt num2小于 (less than)
num1 -le num2小于等于 (less or equal)

示例

if [ "$UID" -eq 0 ]; then
    echo "你是超级用户"
fi

if [ "$#" -gt 1 ]; then
    echo "参数多于1个"
fi

4. 逻辑运算符

操作符说明
! 表达式
表达式1 -a 表达式2与 (and)
表达式1 -o 表达式2或 (or)

注意

  • -a-o 已不推荐使用,建议改用 &&||(但需要放在 [[ ]] 中或分开多个 [ ]

示例

if [ -f "$file" -a -r "$file" ]; then
    echo "文件存在且可读"
fi

if [ ! -d "$dir" ]; then
    echo "不是目录"
fi

5. 复合条件(推荐方式)

更现代的写法是使用多个 [ ] 配合 &&||

if [ -f "$file" ] && [ -r "$file" ]; then
    echo "文件存在且可读"
fi

if [ "$age" -lt 18 ] || [ "$age" -gt 65 ]; then
    echo "年龄不在18-65之间"
fi

6. 特殊注意事项

  1. 变量引用要加引号

    if [ -n "$var" ]; then  # 正确
    if [ -n $var ]; then    # 如果$var为空会出错
    
  2. 空格是必须的

    if [ "$a" = "$b" ]; then  # 正确
    if ["$a" = "$b"]; then    # 错误
    
  3. 字符串与数值比较不要混淆

    if [ "10" -gt "2" ]; then  # 数值比较,正确
    if [ "10" > "2" ]; then    # 字符串比较,可能不是预期结果
    

7. [ ][[ ]] 的区别

特性[ ][[ ]]
类型命令shell关键字
字符串比较需要引号不需要引号
模式匹配不支持支持 ===~
逻辑运算必须使用 -a-o可以使用 &&、`
单词分割会进行不会进行
通配符展开会进行不会进行
POSIX兼容不兼容

示例比较

# [ ] 方式
if [ "$name" = "*.txt" ]; then  # 字面比较
if [ -f "$file" -a -r "$file" ]; then

# [[ ]] 方式
if [[ $name == *.txt ]]; then   # 模式匹配
if [[ -f $file && -r $file ]]; then

8. 实际应用示例

  1. 检查参数数量:
if [ $# -ne 2 ]; then
    echo "用法: $0 参数1 参数2"
    exit 1
fi
  1. 检查文件是否可执行:
if [ -x "/usr/bin/git" ]; then
    echo "Git已安装且可执行"
fi
  1. 安全的字符串比较:
if [ "${var:-}" = "value" ]; then
    echo "var等于value"
fi
  1. 检查是否是闰年(复杂逻辑示例):
year=2024
if [ $((year % 4)) -eq 0 ] && [ $((year % 100)) -ne 0 ] || [ $((year % 400)) -eq 0 ]; then
    echo "$year 是闰年"
fi

总结

[ ] 是 Shell 脚本中最基础的条件测试结构,虽然语法有些古老且严格,但:

  • 它是 POSIX 兼容的
  • 几乎在所有 Shell 中都能工作
  • 是编写可移植脚本的基础
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值