if 语法

if [[ condition ]]; then
    echo "true"
elif [[ another ]]; then
    echo "another"
else
    echo "false"
fi

⚠ 注意:

  • [[ 后、]] 前各有一个空格
  • ;then 在同一行(或 then 单独一行)

[[ ]] vs [ ] vs (( ))

形式 用途
[[ ]] 字符串 + 文件 + 正则,bash/zsh 专用,推荐
[ ](等同 test POSIX 兼容,所有 shell 通用,但语法限制多
(( )) 算术比较,可以用 < > ==

新写 bash 脚本:字符串 / 文件用 [[ ]],数字用 (( ))

字符串判断

if [[ "$name" == "alice" ]]; then echo hi; fi   # 等
if [[ "$name" != "alice" ]]; then echo bye; fi  # 不等
if [[ -z "$var" ]]; then echo empty; fi         # 空
if [[ -n "$var" ]]; then echo not empty; fi     # 非空
if [[ "$name" == a* ]]; then echo "以 a 开头"; fi  # 通配
if [[ "$name" =~ ^[a-z]+$ ]]; then echo "纯小写"; fi  # 正则

$var 永远加双引号——空字符串否则会出语法错。

数字判断

if (( a == b )); then echo equal; fi
if (( a > b )); then echo bigger; fi
if (( a <= 10 && b >= 5 )); then echo in range; fi

# 用 [[ ]] 时
if [[ "$a" -eq "$b" ]]; then echo equal; fi

[[ ]] 数字比较用文字操作符(不能用 >):

操作 意思
-eq
-ne 不等
-gt 大于
-ge
-lt 小于
-le

文件判断

if [[ -e file ]]; then echo "存在"; fi
if [[ -f file ]]; then echo "是普通文件"; fi
if [[ -d folder ]]; then echo "是目录"; fi
if [[ -L link ]]; then echo "是软链接"; fi
if [[ -r file ]]; then echo "可读"; fi
if [[ -w file ]]; then echo "可写"; fi
if [[ -x file ]]; then echo "可执行"; fi
if [[ -s file ]]; then echo "非空"; fi
if [[ file1 -nt file2 ]]; then echo "file1 更新"; fi

组合条件

# 与(&&)
if [[ -f config.ini ]] && [[ -r config.ini ]]; then
    echo "存在且可读"
fi

# 或(||)
if [[ "$env" == "prod" ]] || [[ "$env" == "staging" ]]; then
    echo "是上线环境"
fi

# 非(!)
if [[ ! -d /backup ]]; then
    mkdir /backup
fi

短路求值(一行版)

# 文件存在就 cat
[[ -f config ]] && cat config

# 文件不存在就建
[[ -f config ]] || touch config

# 链式
[[ -d /opt/data ]] || mkdir /opt/data && echo "ready"

case 语句(多分支)

case "$1" in
    start)
        echo "启动"
        ;;
    stop)
        echo "停止"
        ;;
    restart)
        echo "重启"
        ;;
    status|info)               # 多模式
        echo "状态"
        ;;
    *)                          # 默认(其他所有)
        echo "用法: $0 {start|stop|restart|status}"
        exit 1
        ;;
esac

适合脚本接子命令(systemd 风格)。

实战:参数校验

#!/bin/bash
set -e

if [[ $# -lt 1 ]]; then
    echo "用法: $0 <环境>"
    exit 1
fi

env="$1"
case "$env" in
    dev|staging|prod) ;;
    *)
        echo "环境必须是 dev/staging/prod"
        exit 1
        ;;
esac

config="/etc/myapp/${env}.conf"
[[ -f "$config" ]] || { echo "配置 $config 不存在"; exit 1; }

echo "用 $config 启动..."

下一篇:循环。